2014-04-20 12 views
6

Mam następujący prosty program do odczytu z pliku tekstowego (num.txt). Plik tekstowy ma numery 1 2 3 4 5 w każdej linii. Po uruchomieniu programu drukuje 5 razy dwa razy. Czy ktoś może mi powiedzieć, dlaczego tak się dzieje i jak to naprawić? z góry dziękifscanf odczytuje ostatnią liczbę całkowitą dwukrotnie

int main(void) 
{ 
    int number; 
    FILE *file; 

    int i = 0;; 

    file = fopen("num.txt", "r"); 

    while (!feof(file)){ 

     fscanf(file, "%d", &number); 
     printf("%d\n", number); 
     } 

    return 0; 
} 

Oto mój tekst plik num.xtx

1 
2 
3 
4 
5 

A oto wyjścia programu

1 
2 
3 
4 
5 
5 

jest dodatkowa 5

+0

'while (! Feof (plik)) {' :: feof() jest przyczyną problemu – wildplasser

+3

Może Proponuję przeczytać [to] (http://stackoverflow.com/questions/5431941/ while-feof-file-is-always-wrong)? – niklasfi

+1

Jaka jest wartość zwrócona przez fscanf, gdy widzisz ostatnie 5? Założę się, że to nie 1. ;-) –

Odpowiedz

7

Od strony człowieka z scanf rodziny funkcji

Wartość EOF jest zwracany, jeśli koniec wejście zostanie osiągnięty przed wystąpieniem albo pierwsza udana konwersja lub brak dopasowania. EOF jest również zwracany, jeśli wystąpi błąd odczytu, w którym to przypadku jest ustawiony błąd dla strumienia, a errno jest ustawiony, aby wskazać błąd .

Oznacza to, że ostatni sukces fscanf wezwanie czyta ostatnią linię ze strumienia file po którym stan while pętla !feof(file) jest prawdą, ponieważ koniec warunku plik nie jest jeszcze spełnione. Oznacza to, że pętla jest wykonywana jeden dodatkowy czas, a poprzednia wartość zmiennej number jest drukowana ponownie.

Proszę przeczytać - while(!feof(file)) is always wrong

Należy sprawdzić wartość zwracaną scanf zamiast sprawdzania koniec wskaźnika pliku na strumieniu pliku.

#include <stdio.h> 

int main(void) { 
    int number; 
    FILE *file = fopen("num.txt", "r"); 

    // check file for NULL in case there 
    // is error in opening the file 
    if(file == NULL) { 
     printf("error in opening file\n"); 
     return 1; 
    }  

    // check if fscanf call is successful 
    // by checking its return value for 1. 
    // fscanf returns the number of input 
    // items successfully matched and assigned 
    while(fscanf(file, "%d", &number) == 1) 
     printf("%d\n", number); 

    return 0; 
} 
4

Drugi raz fscanf zawiodły i nie napisałem nic do number, dlatego wciąż jest 5 od ostatni raz. Aby dowiedzieć się, czy udało się fscanf, musisz sprawdzić jego wartość zwracaną.

fscanf zwraca liczbę argumentów, które napisał. W twoim przypadku, jeśli zwróci 1, zadziałało; jeśli zwraca 0, nie. To właśnie powinieneś sprawdzić zamiast feof.

while (fscanf(file, "%d", &number) == 1) 
{ 
    printf("%d\n", number); 
}