Merhaba, string ve pointer'larla sorunlarım var. Biraz uzun, ama okuyup yardım edebilecek varsa benim için süper olur.

1)
main() {
char *a;
printf("%d", strlen(a));
}

Bu kod "0" yazıyor. Ama yanına bir de b[10] diye bir char tanımlarsam 11 yazmaya başlıyor. Bu durumda a'nın tanımını char *a="" şeklinde yaparsam yine 0 yazıyor. Burada Codeblocks kullandım, Mingw ve Gcc var içinde. char satrını b'li veya b'siz halde main'in dışına çıkarırsam derleyip çalıştırdığımda bozulup kapanıyor.

DevCpp'de ise "char *a;" tanımı main'deyken çalışmıyor. yanına b[10] ekleyince 0 yazıyor. Tanımı b'li veya b'siz halde main dışına çıkardığımda çalışmıyor. Yine a'ya ="" şeklinde ilk değer verince sorunlar çözülüyor.

Hatam ne, bu fark neden? Örneklerde ilk değer vermeden kullanıyorlar, ben ne yapmalıyım?

2) Asıl sorunum... Yazılan satırı getchar ile alıp mesela \n karakterine kadar bir diziye atamak istiyorum; ama dinamik olsun istiyorum. Yani c!='\n' ise *a'yı bir genişlet ve c'yi ona ekle şeklinde. Aşağıdaki kod olmuyor ve pek işe yarar değil, ama düzene girer mi?

main() {
char *a = "\0", *b = "\0";
char c;
int i = 0;
while ((c = getchar()) != '\n') {
b = (char *)malloc((strlen(a) + 1) * sizeof(char));
strcpy(b, a);
b[strlen(a)] = c;
b[strlen(b)] = '\0';
free(a);
a = (char *)malloc(strlen(b) * sizeof(char));
strcpy(a, b);
free(b);
}
a[strlen(a)] = '\0';
printf("%s, %d, %d", a, strlen(a), strlen(b));
}

 

sorunun tamamına bakamadım kusura bakma ama ilk örnekte bir pointer deklare ediyorsun ama pointerı initialize etmiyorsun. hafızada rastgele bir noktaya point ediyor. bu durumda bunu strlen içine sokmanın sonucu belirsizdir diye düşünüyorum.

kurukafa

Bazı belgelerde, forumlarda initialize etmemişler, hatta etmeye gerek yok yazan bile var. Edince sorun kalmıyor zaten, ama ="" şeklinde sıfır byte olarak tanımlamak doğru mu bilemiyorum. Teşekkür ederim.

fadetoreality

1. char *a; şeklinde yaptığınız deklarasyonda bir initialization olmadığından a bir null pointer olması lazım çoğu derleyicide. bu bağlamda üzerinde strlen() çağırmak tehlikeli ve anlamsız. underflow olması riski var ama sanırım strlen() de bunun için bir kontrol koymuşlar ki 0 veriyor. yanına bir array ekleyince 11 vermesi a nın rastgele bir değere sahip olması ve b nin hemen +1 adresinde bulunmasıyla alakalı.

2. c de dinamik bellek yönetimi biraz zor bir konu. kodu incelemek gerekirse,
gece vakti yanlış söylüyor olabilirim ama, b[strlen(b)] indisler 0dan başladığı için legal olmayan bir statement olsa gerek? aynısı a için de geçerli.
bir de bu ödev falan değilse, çoğu api nin çok güzel string implementasyonları var, hiç biri olmadı standart kütüphanenin(STL) içinde çok güzel bir array<> template i var dinamik bellek yönetimli.

talemon

char e[]={'x', 'y', '\0'}; tanımıyla strlen(e) "2" döndürüyor. Yani e[strlen(e)]=null oluyor sanırım. Hatta dizide birden çok '\0' da olsa yine 2 çıkıyor sonuç.

Stl C++'da galiba, ama onda zaten string tipi de var.

fadetoreality

\0 string sonlandiricisidir. milyon tane de koysan strlen ilk \0'e kadar olan yeri dikkate alir.

yani char e[]={'x', 'y'} de yapsaniz \0 default olarak sona eklenir.

fdegir

kodu mumkun oldugunca degistirmemeye calistim farklari gorebilmen acisindan. Birde b degiskenine temp dedik daha okunabilir olsun diye.

//char *a = "\0", *temp = "\0";

//a'yi allocate edip bos bir string olarak yaratalim
char *a = (char *)malloc(sizeof(char));
a[0] = '\0';

char *temp = NULL;
char c;

//int i = 0;
while ((c = getchar()) != '\n')
{
//a'nin boyutundan 2 fazla yer ayirmamiz lazim biri yeni eklenecek karakter icin
//digeri null karakter icin
//temp = (char *)malloc((strlen(a) + 1) * sizeof(char));
temp = (char *)malloc((strlen(a) + 2) * sizeof(char));
strcpy(temp, a);

temp[strlen(a)] = c;

//temp'de henuz string'in sonu belirten null deger yok ondan strlen ne dondurur mechul
//temp[strlen(temp)] = '\0';
temp[strlen(a)+1] = '\0';

//loop'a girmeden a'yi dinamik olarak olusturdugumuz icin burda artik bir sorun cikmamasi lazim
free(a);

//a icin temp'in uzunlugundan 1 fazla yer ayirmak lazim sondaki null degerler beraber
//a = (char *)malloc(strlen(temp) * sizeof(char));
a = (char *)malloc((strlen(temp)+1) * sizeof(char));
strcpy(a, temp);
free(temp);
}

//buna gerek yok zaten strcpy ile temp'i kopyaladiginda sondaki null karakterde geliyor
//a[strlen(a)] = '\0';

//temp pointeri loopdan cikarken free edilmis ondan burda strlen'e veremezsin.
//printf("%s, %d, %d", a, strlen(a), strlen(temp));
printf("%s, %d", a, strlen(a));

badseed
1

mobil görünümden çık