2012-05-18 21 views
5

Występuje bardzo dziwny błąd podczas próby odczytu z prostego pliku tekstowego za pomocą c wywołania fread().
zrobiłem bardzo prosty program, aby pokazać, że błąd:Dlaczego ftell() pokazuje złe położenie po fread()?

int main(int argc ,char ** argv) { 
    FILE* fh = fopen("adult.txt","r"); 
    if(fh==NULL){ 
    printf("error opening file\n"); 
    exit(0); 
    } 

    int s = 1000; 
    printf("cur before=%d\n",ftell(fh)); 
    char* b = malloc (sizeof(char)*s); 
    int k =fread(b,sizeof(char),s,fh); 
    printf("cur after reading %d bytes =%d\n",k,ftell(fh)); 

    return EXIT_SUCCESS; 
} 

i co otrzymuję jako wyjście:

cur before=0 
cur after reading 1000 bytes =1007 

Czy to normalne? fread zwraca liczbę "1000", ale kursor (z ftell()) pokazuje 1007 i każda pomoc zostanie doceniona.

Odpowiedz

10

To normalne.

'\n' może być reprezentowany przez dwa znaki, dzięki czemu uzyskuje się przekrzywienie.

Jeśli nie chcesz, aby tak się stało, otwórz finał w trybie binarnym.

+0

dziękuję, nie wiedziałem tego. Ale nie rozumiem, dlaczego powrót fread() nie jest taki sam, jak pozycja kursora? – ezzakrem

+1

@ezzakrem Ponieważ 'fread' zinterpretuje koniec wiersza (który może być dwoma znakami) jako jeden znak i zgłosi go jako jeden. –

4

Z dokumentacji ftell:

or binary streams, the value returned corresponds to the number of bytes from the beginning of the file. For text streams, the value is not guaranteed to be the exact number of bytes from the beginning of the file, but the value returned can still be used to restore the position indicator to this position using fseek.

Więc tak, jest to normalne.

+0

dzięki, że pomaga! – ezzakrem

1

Odpowiedź Let_Me_Be jest poprawna. Tłumaczyłem tutaj, że znak końca linii (EOL) jest zależny od systemu operacyjnego. Na przykład w systemie Windows, jeśli otworzysz plik z "r" (lub nie binarnym), wtedy gdy pojawi się sekwencja "\ r \ n", system operacyjny zwróci tylko "\ n". W ten sam sposób, gdy piszesz w pliku, który nie jest otwarty w trybie binarnym, to w Windows napisze "\ r \ n", gdy napiszesz "\ n". W systemach uniksowych nie ma takiego tłumaczenia przez system operacyjny. Klasyczne komputery Mac używają "\ r" dla znaku końca linii, ale myślę, że teraz używają "\ n" dla EOL. Mam nadzieję, że usunie modne słowo "\ n", które ma być reprezentowane (możliwe) przez wiele znaków (\ r \ n).

+0

dziękuję! to sprawia, że ​​jest to bardzo jasne. – ezzakrem