[]

C Soruları

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  (20.10.08 00:17:30) 
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  (20.10.08 00:21:58) 
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  (20.10.08 00:34:39) 
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  (20.10.08 00:48:28 ~ 00:51:35) 
\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  (20.10.08 11:51:36 ~ 11:52:26) 
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  (20.10.08 22:19:23) 
1
buraya yazılanların hakları Sir Anthony Hopkins'e aittir.
yazan eden compumaster, ilgilenen eden fader
modere edenler angelus, Artibir, aychovsky, baba jo, basond, compumaster, deckard, duyulmasi gerektigi kadar, fader, fraise, groove salad, kahvegibi, kaymaktutmayansicaksut, kibritsuyu, monstro, pandispanya, robin, ron dennis
bu sitede yazılanların hiçbiri doğru değildir. site içeriği küçükler için sakıncalı olabilir. yazılardan yazarları sorumludur. kaynak göstermeden alıntılanamaz. devlet tarafından atanmış bir kurumun internet üzerinde kimin hangi bilgiye ulaşıp ulaşamayacağına karar vermesi insan haklarına aykırıdır. web siteleri kullanıcıların istekleri doğrultusunda bağlandıkları yerlerdir. kullanıcılar isterlerse bir web sitesine bağlanmayabilirler. bu güçleri ve imkanları mevcuttur. bir kullanıcı bir siteye bağlanmak istiyorsa bu onun tercihi ve hakkıdır. bağlanmak istemiyorsa bu yine onun tercihi ve hakkıdır. halkın kendisine hizmet etmesi için görevlendirdiği kurumlar hadlerini aşıp halka neye ulaşıp ulaşmayacağını bilmeyen cahil cühela muamelesi edemezler. ebeveynlerin çocuklarını sakıncalı içeriklerden koruması için çok sayıda bedava ve ücretli yazılım mevcuttur. bu yazılımlar bir web tarayıcısını kullanmaktan daha karmaşık teknik bilgi gerektirmemektedir. devletin milletini küçük düşürmesi ve ebleh yerine koyması yasaktır. Skimlinks ile linkler üzerinden yönlendirme payı alınmaktadır.