2014-04-20 10 views
6

Ho il seguente programma semplice da leggere da un file di testo (num.txt). Il file di testo ha numeri 1 2 3 4 5 in ogni riga. Quando eseguo il programma, stampa 5 due volte. Qualcuno può dirmi perché sta succedendo questo e come risolverlo? grazie in anticipofscanf legge l'ultimo intero due volte

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; 
} 

Ecco il mio file di testo num.xtx

1 
2 
3 
4 
5 

Ed ecco l'output del programma

1 
2 
3 
4 
5 
5 

C'è un extra di 5

+0

'while (! Feof (file)) {' :: feof() è la causa del problema – wildplasser

+3

maggio vi consiglio di leggere [questo] (http://stackoverflow.com/questions/5431941/ mentre-feof-file-è-sempre-male)? – niklasfi

+1

Qual è il valore restituito da fscanf quando si vede l'ultimo 5? Scommetto che non è 1. ;-) –

risposta

7

Dalla pagina man di scanf famiglia di funzioni,

Il valore EOF viene restituito se l'estremità di ingresso viene raggiunta prima verifica sia la prima conversione di successo o un guasto corrispondente. EOF viene inoltre restituito se si verifica un errore di lettura, nel qual caso viene impostato l'indicatore di errore per lo streaming e errno è impostato per indicare l'errore .

Ciò significa che l'ultimo successo fscanf chiamata legge l'ultima riga dal flusso file dopo di che la condizione del ciclo while!feof(file) è vero, perché la fine della condizione di file non è ancora soddisfatta. Ciò significa che il ciclo viene eseguito una volta in più e il valore precedente della variabile number viene stampato di nuovo.

Si prega di leggere questo - while(!feof(file)) is always wrong

Si dovrebbe controllare il valore di ritorno di scanf invece di controllare l'indicatore di fine file sul flusso di file.

#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

La seconda volta fscanf fallito e non ha scritto nulla a number, ecco perché è ancora 5 da l'ultima volta. Per sapere se fscanf è riuscito, è necessario controllare il suo valore di ritorno.

fscanf restituisce il numero di argomenti che ha scritto. Nel tuo caso, se restituisce 1, ha funzionato; se restituisce 0, non lo ha fatto. Questo è ciò che dovresti controllare invece di feof.

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