PDA

Tam Sürümünü Görmek İçin : C de bir String içinde kaç string var? Yardım!


fairblack
02/02/2007, 07:17
Arkadaşlar bir string içinde kaç tane o string den olduğunu öğrenmem gerekiyor. interneti baya arastirdim fakat bulamadım. örneğin ;
char katar[] = "bu bir denemedir evet denemedir"; // olsun
char aranan[] = "denemedir";
katar içerisinde iki adet "denemedir" kelimesi geçiyor yani programa bunu buldurmak istiyorum.
Yardımcı olursanız sevinirim..
Teşekkürler


bluekid
02/02/2007, 16:28
döngü {
strstr kullanarak arat
eğer bulduysan
bulduğun pozisyonu arananın uzunluğu kadar ileriye al
sayacı ++
bulamadıysan
döngüden çık
}

sayacı yazdır

fairblack
02/02/2007, 18:15
Bulduğum pozisyonu arananin uzunluğu kadar nasıl ileri alabilirimki ayrica imlecin en son konumunu nasıl bulabilirim.

acehreli
02/02/2007, 19:26
Bir dizginin uzunlugunu strlen ile bulabilirsin.

Bir isaretciye bir deger ekledigin zaman, onu o deger kadar "ileri almis" olursun:

char * isaretci = /* bir sey */;
isaretci += 2; // simdi ucuncu karakteri gosteriyor

Tabii 'katar' bir dizi olarak tanimlandigi icin onu boyle bir aritmetik islemde kullanamazsin. Ama zaten ayri bir isaretci kullanacaksin herhalde:

char * kaldigimYer = /* bunu strstr soyleyecek */;
kaldigimYer += /* bunu da strlen... */;

Ali

fairblack
02/02/2007, 19:36
çok teşekkür ederim ilginiz için c de değişkenlerin önüne gelen yıldızı halen çözemedim. c de yıldızlar ne işe yarar.

acehreli
02/02/2007, 21:39
O yildizi kucumseme ve cozmek icin sabirli davran. :) C'nin en zor anlasilan konusu olan isaretcilerle ilgilidir.

Isaretcilerle ilgili iki anlamda olabilir:

1) Bildirim sirasinda:

char * birIsaretci;

O durumda gordugunde * karakterini ondan onceki tUr ismiyle ilgili olarak dusun. Nasil

char birKarakter;

gordugumuzde "birKarakter bir char'dir" diyorsak,

char * birIsaretci;

gordugumuzde de "birIsaretci bir char isaretcisidir" deriz.

2) Kullanim sirasinda:

printf("%d", *birIsaretci);

Bir isaretcinin adindan once yazildiginda * karakterinin anlami, o isaretcinin gosterdigi nesneye erismektir. Yani yukardaki satiri soyle okuyabiliriz: "birIsaretci'nin gosterdigini yazdir".

Ali

quasimodo
03/02/2007, 01:51
C deki pointerlari anlayabilmek icin sanirim adres kavraminin iyi bilinmesi gerekiyor.
C deki char, int, float, double.. vs turlerinden ayri olarak birde adres turu bulunmaktadir. Bu diger turlere benzemeyen adres turu yazilimsal olarak diger turler gibi sadece bir sayidan ibaret degildir. Adres turunun iki bileseni vardir.
1- Bellekte yer gosteren bir sayi
2- O adresteki bilginin derleyici tarafindan nasil yorumlanacagini bildiren bir tur
Tamsayi sabitlerini atadigimiz degiskenlere int (yani 2 , -3 gibi sabit sayilari int turunden degiskenlere), Gercek sayi sabitlerini (3.2 , -5.3) atadigimiz degiskenlere float/double ve Iste bu adres sabitlerini atadigimiz degiskenlere gosterici/isaretci (pointer) denir.
Göstericilerin bildirimleri
int * p;
char * ch;
double * do;
seklindedir.
Bu sekilde bir bildirim yaptigimizda derleyici calisma zamaninda (run time) bize belirtilen tur kadar yer ayirir. char 1 byte int 2 / 4 byte ....
Bu yer ayirma islemi calisma zamaninda yapildigindan dolayi ayirilan bellek gozunun icindeki bilginin bizim ayirdigimiz ture uygun bir yer oldugunun bilinmesi mumkun degildir. Dolayisiyla;
int * p;
*p = 12;
ifadesi hatadir hemde cok buyuk. Bunu denedimde hata almadim diyorsaniz bu tamamen tesaduftur. Boyle bir kullanimda derleyici bellekte rastgele bir yer ayirir ve bu yer belkide sistem icin gerekli bir yerde olabilir. Dolayisiyla bu hatalarla karsilasmamak icin programcilar genellikle gostericiye bir NULL yada 0 ilk degeri atarlar. Ama bu atama yapilsa bile;
int * p = NULL;
*p = 12;
ifadesi yanlistir.

Birazda Gosterici operatorlerine deginelim. 3 tane gosterici operatoru mevcuttur.
1- icerik operatoru *
2- adres operatoru &
3- index operatoru [n]

* operatorunu Ali Hocam anlatmis sanirim
& operatoru bir onek olan operatordur ve onune konuldugu nesnenin bellekteki adresini gosterir.
[n] operatoru ise operandi adres olan tek operandli ve sonek operatordur.
int * p = NULL;
int array[5] = { 3, 5, 7, -5, 0};
p = &array[0]; /*dizinin ilk elemaninin adresini gostericinin
adresine atadim, artik p gostericisi dizinin ilk
elemanini isaret ediyor dolayisiyla */
printf("%d", *p); // ekranda 3 gorunecektir.

Umarim yardimci olmusumdur bi nebze. Yanlislarim varsa lutfen duzeltin...

quasimodo
03/02/2007, 01:53
Peki ben bisiy soracagim. Asagidaki ifade neden yanlis ?
char * p = "merhaba";
char ch;
&ch = p;

Sabahi
03/02/2007, 02:34
Peki ben bisiy soracagim. Asagidaki ifade neden yanlis ?
char * p = "merhaba";
char ch;
&ch = p;


1) Dile aykiri (char * p1; char * p2; p1=p2; gibi iki ayni tur assignment alir ve & operatoru assignment'in solunda yer almaz)
2) sizeof(char) != sizeof(p) oldugu icin eger derleyici gormezden gelse bile 4 byte i 1 byte a nasil sigdiracaktiniz?

quasimodo
03/02/2007, 02:38
iyide oradaki p yanlizca "merhaba" string inin baslangis adresini isret ediyor. bende bir adresi baska bir adrese atiyorum. Bunun nesi yanlis...?

neden ch ile p nin buyuklukleri eşit değil ? p m nin adresi değil mi ? E m de bir char olduğuna gore ...

ceeyt
03/02/2007, 02:40
sabahinin 2. sikta verdigine biraz daha dikkat et. p olarak tanimladigin bir isaretci ve 32 bit'le ifade edilebilecek br adres vermesi gerekiyor,dolayisiyla boyu 4 byte. ch ise char turunden ve 1 byte

quasimodo
03/02/2007, 02:49
peki ch nin adresiyle "merhaba" daki 'm' nin adresini nasıl birbirine esitleyebilirim ...

acehreli
03/02/2007, 02:53
quasimodo, yazdiklarin icin tesekkurler ama bir noktayi duzeltmek gerekiyor:

int * p; *p = 12; orneginde "derleyici bellekte rastgele bir yer ayirir" diyorsun.

p'nin degeri rastgele bir degerdir ama bu, biz ona bir ilk deger vermedigimiz icin oyledir. Yoksa derleyicinin rastgele ayirdigi bir yer yoktur.

Eger derleyicinin p icin yer ayirmasindan soz ediyorsan, p'nin neyin parcasi olarak tanimlandigina bagli olarak bir yer ayrilir tabii. Ornegin, p bir yerel nesneyse, program yigitinin bir parcasi onun icin kullanilir. Eger p bir yapinin parcasiysa, o yapi nerede yasiyorsa onun parcasi olarak p'nin de yeri vardir.

*p = 12; yaptigimiz an "tanimsiz davranis"la karsi karsiyayizdir; cunku "hicbir yeri gostermeyen" bir isaretciyi kullanmisizdir.

Ayrica, [] islecinin aslinda * islecini bir kullanimi oldugunu soylemek gerek. Kernighan ve Ritchie'nin kitaplarinda soyledikleri gibi, a[b] islemi aslinda tamamen *(a + b) isleminin esdegeridir. Yani aslinda yazim acisindan bir kolayliktan baska bir sey degildir.

Sordugun soruya gelince, C'de ve C++ sol-deger (lvalue) ve sag-deger (rvalue) diye kavramlar vardir. Bunlar, hangi ifadelerin atama islecinin hangi tarafinda yer alabilecegini belirlemek icin kullanilirlar.

Sag-degerler, atama islecinin sol tarafinda bulunamazlar. Ornegin 1+1 isleminin sonucu bir sag-deger oldugu icin onu ancak sag tarafta kullanabiliriz:

int a = 0;
a = 1+1; // dogru
1+1 = a; // HATA

Ayni sekilde, & islecinin sonucu bir sag-deger oldugu icin onu ancak sag tarafta kullanabiliriz:

char ch = 'a';
char * p = 0;
p = &ch; // dogru
&ch = p; // HATA

Bunu anlamak bayagi kolay aslinda: O islem calissa, programdaki hangi nesnenin degerinin degismesini bekleriz? Ya da o islemin nasil bir etkisi olmali?

Ali

acehreli
03/02/2007, 03:05
quasimodo, en son sordugun soruyu anlayamiyorum. Iki degisik nesnenin adresini esitlemekle ne kastediyor olabilirsin? Birisi bir dizi, kendi adresinde oturuyor; oteki bir karakter, kendi adresinde oturuyor.

Adreslerinin esit olmasi icin ayni yerde olmalari gerekir. Onu basarirsak, bilgisayarlarin bellek sorunu kalmazdi herhalde; herseyi ayni adrese koyardik :D

Ali

quasimodo
03/02/2007, 03:09
struct YAPI{
int num;
int * p;
char ch;
};

int main()
{
struct YAPI yapi;
*yapi.p = 12; /* Bunu diyemem cunku guvenli olup
olmadigi belli degil */
yapi.p = (int* ) malloc(sizeof(int)); /* Boyle yaparsamda yapi icin
ayrilmis olan yerden baska bir yerde bana yer ayiracak */
return 0;
}

Ama bu olay yapinin mantigina aykiri degilmi (yer ayirma islemi) ? Yani yapi elemanlari sirali olmak zorunda degil mi?

myavuzselim
03/02/2007, 03:19
Yapinin elemani *p (p'nin gosterdigi char) degil ki, p'nin kendisi.

YAPI (malloc'dan once):

--------
| num |
--------
| p |----> ??
--------
| ch |
--------


YAPI (malloc'dan sonra):

| |
-------- ----------
| num | | |
-------- ----------
| p |----> | |
-------- ----------
| ch | | |
-------- ----------
| |

myavuzselim
03/02/2007, 03:35
Ya da soyle cizelim:


yapi (yapi.p = malloc(...)'dan once):

223 | 13 | DOLU
-------- ----------
num | ?? | 224 | 'c' | BOS
-------- ----------
p | ?? | 225 | 2 | BOS
-------- ----------
ch | ?? | 226 | 'm' | DOLU
-------- ----------
227 | 'x' | DOLU
----------

228 YOK!
229 YOK!


yapi (yapi.p = malloc(...)'dan sonra):

223 | 13 | DOLU
-------- ----------
num | ?? | 224 | 'c' | BOS
-------- ----------
p | 225 | 225 | 2 | DOLU
-------- ----------
ch | ?? | 226 | 'm' | DOLU
-------- ----------
227 | 'x' | DOLU
----------

228 YOK!
229 YOK!