PDA

Tam Sürümünü Görmek İçin : while(!feof(oku)) hatalı çalışıyorr


tunahanabi
12/12/2004, 04:02
while ( !feof( oku ) ){
}

gibisinden bir komut ile dosyaya değer yazdırdığımda son değeri iki defa yazıyo. başka bi dosyadan okuma yapıp yazınca son satırı (ki bu satıra ENTER ile inilmiş durumda) okumaması gerekirken varmış gibi davranıp döngüyü tekrar çeviriyor. so n değeri tekrar işleme sokuyor.
kaynak dosya 10 satırdan oluşurken hedef dosya 11 satır oluyor.
while döngüsü içinde bazı işlemler var. onun için kaynak dosyayı direk kopyalayamıyorum.

eof u denedim ama olmadı galiba yanlış kullandım.
==NULL gibisinden bişeyler yapmayı denedim o da olmadı.

nasıl halledebilirim bu sorunu yardımcı olursanız sevinirim.


acehreli
12/12/2004, 09:02
tunahanabi, bize problemi gosteren kucuk bir program gonderebilir misin? Anlattigin kadari hatanin nerede oldugu konusunda bir fikir vermiyor. Ornegin su program bende istendigi gibi, son satiri tekrarlamadan calisiyor:


#include <stdio.h>

int main()
{
FILE * giris = fopen("deneme.txt", "r");

while (!feof(giris))
{
char satir[1000];
printf(fgets(satir, sizeof(satir), giris));
}

return 0;
}


Bir kUtUgun sonuna gelinip gelinmedigi bilgisinin C ile C++'ta farkli oldugunu biliyorum. Ama su anda ayrintilardan emin degilim. Yanilmiyorsam C'de (veya C akimlarinda) kUtUk sonunda oldugunun anlasilmasi, bir okuma yapMAdan bilinebiliyor. C++ akimlarinda ise, kUtUgun sonunda bile olsak, bu bilgiyi alabilmemiz icin, ya da o akimi "akim sonu" durumuna sokabilmemiz icin, basarisiz olan bir okuma yapmamiz gerekir.

Senin bu durumdan etkilenip etkilenmedigini bilmiyorum ama yine de soylemek istedim. Dedigim gibi, biraz daha kod goster lutfen... :)

Ali

esabah
12/12/2004, 11:40
ayny şey benim de başım agelmişti ve ben sorunu okuduğum dosya da buldum imleç kayıtların bittiği satır da değil de bi altta durduğu zaman son kaydı iki kere alıyordu ileci yukarı çekip save yaptığımda düzeldi. bi dene istersen belki sende de aynı sorun oluyordur

tunahanabi
12/12/2004, 18:23
imleci yukarı kaydırınca bende de bu sorun ortadan kalkıyor onu biliyorum ama kaynak dosyayı herzaman ben yazmayacağım. bazı yerlerde exe kendisi bi dosya oluşturup daha sonra tekrar okuyacak. exe dosya oluştururkende imleci sürekli, senin dediğin gibi bi alta getiriyor. bu durumda da bi sonraki okumada aynı sorun yeniden ortaya çıkıyor.

tunahanabi
12/12/2004, 18:39
Aşağıda kodları gönderiyorum.
exe çalışırken
..tc\bin\ altında poly.gon ve input2.usr dosyalarına ihtiyaç duyuyor. onlarında içine yazılı olan değerlerini yolluyorum. notepad ile yazıp ilgili yerlere kaydedebilirsiniz.
burada input2.usr dosyasında 9 değer olmasına rağman ekrana 10 değer basıyor. son değeri iki defa basıyor.

ÖNEMLİ: poly.gon ve input2.usr dosyalarını kaydederken kursörü enter ile en alttaki satıra getirin. (yazılı satırların en sonuncusunun altında olacak şekilde)
(en sonda boş bi satır olacak yani) :rolleyes:



#include <stdio.h>
#include <conio.h>
int main()
{
int i,j,c=0;
double N,xp[50],yp[50],x,y;
clrscr();
FILE *polyoku; //poly.gon dosyasi okunuyor.ilk satirdan N sonrakilerden xp ve yp okunuyor
if((polyoku=fopen("poly.gon","r"))==NULL)
printf("Dosya acilamadii!!\n");
else{
fscanf( polyoku , "%lf",&N); //poligon kose sayisi
// printf("%lf\n",N);
for(i=0; i<N; i++)
{
fscanf( polyoku , "%lf %lf",&xp[i],&yp[i]); //poligon kose koordinatlari
// printf("%lf %lf\n",xp[i],yp[i]); // okunan kose koordinatlarini ekrana bas
} //end of for
} //end of else
fclose(polyoku);
/************************************************** ************
FILE*input: poligon icinde olup olmadigi test edilecek noktalar
input2.usr dosyasindan okunacak
************************************************** ************/
FILE *input;
if ( ( input = fopen( "input2.usr", "r" ) ) == NULL )
printf( "Dosya acilamadi 2\n" );
else {
while (!feof(input)){
fscanf( input, "%lf%lf", &x, &y);
j=0;
c=0;
for (i=0; i<N; i++) { //herbir x y noktasi icin pointInPolygon testi
j++;
if (j==N) j=0;
if (yp[i]<y && yp[j]>=y || yp[j]<y && yp[i]>=y)
{
if(xp[i]+ (y - yp[i]) / (yp[j] - yp[i])*(xp[j] - xp[i]) < x)
{
c = !c;
}} //if lerin sonu
} //eof for
printf("%lf %lf ",x,y); //degerlendirmeye giren herbir x ve y nin degerlerini ekrana bas
if(c==0) printf(" disarda\n");
else printf(" icerde\n");
} //end of while
} //end of else
getch();
return 0;
}


poly.gon dosyasını içeriği
==================
5
0.506 0.724
0.515 0.718
0.509 0.708
0.499 0.711
0.497 0.719

==================

input2.usr dosyasının içeriği
====================
0.505 0.717
0.509 0.713
0.502 0.714
0.494 0.705
0.514 0.724
0.505 0.717
0.509 0.713
0.502 0.714
0.514 0.724

===========

acehreli
12/12/2004, 19:38
Daha derinine incelemedim ama hata fscanf'in donus degeri gozardi edildigi icin olusuyor:


while (!feof(input)){
fscanf( input, "%lf%lf", &x, &y);


KUtUk sonunda olmamak demek kutukte x ve y icin degerler bulundugu anlamina gelmez tabii ki. fscanf basarisiz olunca, x ve y kendilerine son atanan degerleri tutmaya devam ediyorlar.

Soyle bir cozum ise yaradi:


while (!feof(input)){
if (fscanf( input, "%lf%lf", &x, &y) == 2)
{
/* ... */
}


Baska hatalar da olabilir; ben daha fazla bakmadim.

Ali

tunahanabi
12/12/2004, 20:32
while (!feof(input)){
x=-1;
fscanf( input, "%lf%lf", &x, &y);
if (x==-1) break;
...............

şeklinde yaptım biraz önce ve çalıştı.

acehreli
12/12/2004, 22:32
tunahanabi, senin yonteminin iki tane sakincasi var:

1) Ya x zaten -1 olarak gelirse? (Eger senin durumunda bu deger zaten yasal degilse, bunun zaten ayrica denetlenmesi gerekir.)

2) Ya giriste bir hata olur ve y hic okunamazsa? Onun icin de ayri bir deneme mi yapmamiz gerekecek? Peki ya 2 degil 3 deger okumamiz gerekiyorsa?

Islemleri ayri ayri islevleri icinde yapmak kodu cok kolaylastirir ve guzellestirir. Bence burada koordinatlari_oku gibi bir islev yazmak cok uygun olur:


// Uygunsa 0'dan farkli bir sayi, degilse 0 dondurur
int uygun_deger(double deger)
{
double const en_kucuk_deger = 0.0;
double const en_buyuk_deger = 100.0;

return ((deger >= en_kucuk_deger) &&
(deger <= en_buyuk_deger));
}

// Basariyla okursa sifirdan farkli bir sayi, degilse 0 dondurur
int koordinat_degeri_oku(FILE * giris, double * deger)
{
return ((fscanf(giris, "%lf", deger) == 1) &&
uygun_deger(*deger));
}

// Basariyla okursa sifirdan farkli bir sayi, degilse 0 dondurur
int koordinatlari_oku(FILE * giris, double * x, double * y)
{
return (koordinat_degeri_oku(giris, x) &&
koordinat_degeri_oku(giris, y));
}


Ondan sonra kod icinden soyle cagirabilirsin:


while (!feof(input)){
if (koordinatlari_oku(input, &x, &y))
{
/* ... */
}


Ali

tunahanabi
13/12/2004, 14:40
benim yazacağım kodda değerler radyan cinsinden olacak ve 0 dan küçük bir değer girilmeyeceği için bu haliyle kod düzgün çalışacak.
ama senin dediğin daha genel anlamda düşünüldüğünde başka uygulamalarda kullanılmalı derim.
yardımlarınız için teşekkürler.