29 Mayıs 2010 Cumartesi

C Dosya Okuma ve Adresleme Sorunu


Elimi alıştırmışken arayıda soğutmadan C ile ilgili bir yazı daha eklemek istedim.Bu yazıda C de bir metin belgesinden okuma yaparken karşılabilecek sorunu ve çözümünü anlatacağım.

İlk önce elimizde şu şekilde bi
deneme.txt dosyası olduğunu varsayalım ve bunu bir köşeye koyalım;
mustafa
kaya
muska

Ve amacımız metin belgesinden okuma yapıp her bir satırı bir önceki yazımda anlattığım pointer arrayde tutmak olsun.

Bunun için bi do-while döngüsü ile satır sonuna kadar okuma yapacak ve okuduğu satırları *degisken[100] dizimize okudukça atacak aşağıdaki kodlarımızı hazırlıyorum ve kodumu derliyorum.



#include
#include

int main(int argc, char *argv[])
{
char *
degisken[50];
int sayac=0;
char *kontrol;
char satir[50];
int i;

FILE *kaynak=fopen("deneme.txt","r");
do{
if(kontrol!=NULL)
{
kontrol=fgets(satir,50,kaynak);
degisken[sayac]=satir;
printf("satir:%s,adres:%p",
degisken[sayac],degisken[sayac]);
sayac++;
}
}while(kontrol!=NULL);

for(i=0;i
{
printf("%s\n",degisken[i]);
}


system("PAUSE");
return 0;
}


Kodun ekran çıktısı şu şekilde;

satir:mustafa,adres:0022FE10
kaya,adres:0022FE10
muska,adres:0022FE10
muska,adres:0022FE10
muska,adres:0022FE10
muska,adres:0022FE10

Ekran çıktısındanda anlaşıldığı üzere döngü içerisinde iken sıra ile baktığımızda döngü içerisinde iken
degisken dizimize ekliyor fakat döngüden çıktıktan sonra ve dizideki tüm elemanları ekrana yazdırmak istediğimizde tüm elemanlar okunan son satir oluyor şeklinde gözüküyor.Ama dikkatimizi çeken nokta adresin hep aynı olması.İşte sorunun sebebide burda, okunan satırın adresini degisken dizimize alıyoruz.Ve dizinin elemanlarını çağırdığımızda hep son satırın adresini gösteriyor ve son satırda muska olduğu için tüm elemanlar muska oluyor.Aslında döngü içerisinde iken de son satırın adresini tutuyordu fakat henüz bir sonraki satırı okumadığı için o anki satırın adresini gösteriyordu bize normal gibi geliyordu.Umarım fazla karışık olmadı.

Peki buna çözüm üretmek için şimdi neler yapacağız?

Öncelikle fgets ile satırı okurken ilk olarak satırın byte olarak alabilecek uzunluğunu elle değil
strlen(satir) şeklinde yapalım ki dinamik bir yapı olsun.Bunu yaptıktan sonra yapmamız gereken önemli iş degisken dizimizin her bir elemanın boyutunu okunan satıra göre dinamik olarak ayarlamak yani mallocate etmek.Bu işlemide yaptıktan sonra diğer yapmamız gereken iş ise ve önemli bir nokta atama yaparken degisken[sayac]=satir; şeklinde değil strcpy fonksiyonu kullanarak yapmak yani;
strcpy(degisken[sayac],satir);


Bu düzenlemeleri yaptıktan sonra kodumuzun yeni hali;

int sayac=0;
char *temp[50];
char *kontrol;
char satir[50];
int i;

FILE *kaynak=fopen("deneme.txt","r"); //text dosyasından satır satır okuyup bunu diziye atmak istiyorum.

do{

kontrol=fgets(satir,sizeof(satir),kaynak);
if(kontrol!=NULL)
{
//çözüm...!
temp[sayac]=malloc(strlen(satir)+1);
strcpy(temp[sayac],satir);
//temp[sayac]=satir;
printf("satir:%s,adres:%p",temp[sayac],temp[sayac]);
sayac++;
}

}while(kontrol!=NULL);


for(i=0;i<>
{
printf("\nsatir adresi: %p,satir:%s\n",temp[i],temp[i]);
}

satir:mustafa,adres:002D1018
kaya,adres:002D0F70
muska,adres:002D1030
mustafa,adres:002D1018
kaya,adres:002D0F70
muska,adres:002D1030

Görüldüğü gibi
her bir satırı farklı bir yerde tutuyoruz ve böylece sorun halledilmiş oldu.

0 yorum:

 

Mustafa Kaya. Copyright 2009 All Rights Reserved Revolution Two Church theme by Brian Gardner Blog Skins