2013-07-15 19 views
5

Zakładając, że mamy plik tekstowy o nazwie hi.txt który zawiera następujący ciąg:wyjście Nieoczekiwany podczas korzystania fseek

AbCdE12345

powiedzmy możemy uruchomić ten kod:

int main() { 
    FILE *fp; 
    fp = fopen("hi.txt","r"); 
    if(NULL == fp) { return 1; } 
    fseek(fp,-1, SEEK_END); 
    while (ftell(fp) > 0) { 
    printf("%c",fgetc(fp)); 
    fseek(fp,-4, SEEK_CUR); 
    } 
    fclose(fp); 
    return 0; 
} 

Po uruchomieniu tego kodu wydrukowano: 3EbCd

Kiedy próbowałem zgadnąć, co to drukuje, myślałem, że powinno to być 52d. Czy ktoś może wyjaśnić, co się tutaj wydarzyło?

Odpowiedz

15

Wygląda na to, że na końcu pliku znajduje się niedrukowalny znak końca wiersza. To właśnie zostanie wydrukowane jako pierwsze. Następnie pozycja jest przenoszona kolejno do 3, E i b. W tym momencie zmiana pozycji przez -3 kończy się niepowodzeniem, ponieważ lokalizacja stanie się -2. Kursor pliku pozostaje tam, gdzie był, tj. Pod numerem C, który zostanie wydrukowany obok. Następująca próba zmiany położenia również nie powiedzie się, więc zostanie wydrukowany. Następna repozycjonowanie powiedzie się, kończąc pętlę.

Aby wykryć sytuacje, kiedy fseek jest ignorowany, sprawdzić jego wartości zwracanej, tak:

while (ftell(fp) > 0) { 
    printf("%c",fgetc(fp)); 
    // Successful calls of fseek return zero 
    if (fseek(fp,-4, SEEK_CUR)) { 
     // Exit the loop if you can't jump back by 4 positions 
     break; 
    } 
} 
+0

Działa! Dzięki !!! – Robert777

4

przypadku plików otwartych w trybie tekstowym przesunięcie przekazane fseek ma sens tylko dla wartości zwróconych przez ftell. Więc przesunięcie niekoniecznie musi być w bajtach. Spróbuj otworzyć plik w trybie binarnym:

fp = fopen("hi.txt", "rb"); 

i sprawdź, czy wyniki są różne.

Powiązane problemy