2009-09-15 12 views
20

Sto utilizzando il seguente codice C per ricevere input dall'utente fino a quando non si verifica EOF, ma il problema è che questo codice non funziona, termina dopo aver preso il primo input. Qualcuno può dirmi cosa c'è di sbagliato in questo codice. Grazie in anticipo.Rilevamento di EOF in C

float input; 

printf("Input No: "); 
scanf("%f", &input); 

while(!EOF) 
{ 
    printf("Output: %f", input); 
    printf("Input No: "); 
    scanf("%f", &input); 
} 
+3

Nota: Supponendo che l'input dell'utente non viene convogliata, controllando per EOF probabilmente non è l'ideale, dal momento che IIRC di solito questo significa che l'utente deve premere Ctrl + D per smettere, che non è ovvio – Brian

risposta

40

EOF è solo una macro con un valore (solitamente -1). È necessario testare qualcosa contro EOF, ad esempio il risultato di una chiamata getchar().

Un modo per verificare la fine di un flusso è con la funzione feof.

if (feof(stdin)) 

nota, che la 'fine del flusso' stato sarà impostato solo dopo un fallito leggere.

Nell'esempio si dovrebbe probabilmente controllare il valore di ritorno di scanf e se questo indica che nessun campo è stato letto, quindi controllare la fine del file.

+2

Grazie Charles Bailey. – itsaboutcode

+3

E osserva il commento di Brian: stdin normalmente non registra EOF, poiché c'è sempre più che l'utente può digitare. Su un sistema Unix, questo di solito significa control-D. –

+0

Dipende da cosa intendi il mio "normalmente". Se hai reindirizzato lo stdin (file o pipe, unix o windows), EOF viene in genere segnalato correttamente. In un terminale unix interattivo^D di solito funziona, in modalità testo di Windows,^Z all'inizio di una linea funziona. –

8

EOF è una costante in C. Non si sta verificando il file effettivo per EOF. Hai bisogno di fare qualcosa di simile

while(!feof(stdin)) 

Ecco la documentazione per feof. È inoltre possibile controllare il valore restituito di scanf. Restituisce il numero di articoli convertiti con successo, o EOF se raggiunge la fine del file.

+0

la funzione FILE contiene una variabile che sarebbe meglio testare rispetto all'utilizzo di EOF? sembra proprio che sarebbe meglio controllare uno stato sul puntatore del file reale, piuttosto che usare una strana funzione che funziona solo a metà tempo. – MarcusJ

0

come punto di partenza si potrebbe provare a sostituire

while(!EOF) 

con

while(!feof(stdin)) 
4

Un altro problema è che si sta leggendo solo scanf("%f", &input);. Se l'utente digita qualcosa che non può essere interpretato come un numero in virgola mobile C, come "pi", la chiamata scanf() non assegnerà nulla a input e non progredirà da lì. Ciò significa che cercherà di continuare a leggere "pi", e in mancanza.

Data la modifica a while(!feof(stdin)) che altri poster stanno raccomandando correttamente, se si digita "pi" ci sarebbe un ciclo infinito di stampa del valore precedente di input e la stampa del prompt, ma il programma non elaborerebbe mai alcun nuovo ingresso.

scanf() restituisce il numero di assegnazioni alle variabili di input effettuate. Se non ha assegnato alcun incarico, significa che non ha trovato un numero a virgola mobile, e dovresti leggere più input con qualcosa come char string[100];scanf("%99s", string);. Questo rimuoverà la stringa successiva dal flusso di input (fino a 99 caratteri, in ogni caso - l'extra char è per il terminatore null sulla stringa).

Si sa, questo mi ricorda tutti i motivi per cui odio lo scanf(), e perché io uso fgets() invece e quindi forse lo analizzo usando sscanf().

-1

Si desidera controllare il risultato di scanf() per assicurarsi che ci sia stata una conversione corretta; se non ci fosse, allora una delle tre cose è vera:

  1. scanf() sta soffocando su un personaggio che non è valido per la conversione specificatore% f (vale a dire, qualcosa che non è una cifra, punto, 'e' o 'E');
  2. scanf() ha rilevato EOF;
  3. scanf() ha rilevato un errore nella lettura di stdin.

Esempio:

int moreData = 1; 
... 
printf("Input no: "); 
fflush(stdout); 
/** 
* Loop while moreData is true 
*/ 
while (moreData) 
{ 
    errno = 0; 
    int itemsRead = scanf("%f", &input); 
    if (itemsRead == 1) 
    { 
    printf("Output: %f\n", input); 
    printf("Input no: "); 
    fflush(stdout); 
    } 
    else 
    { 
    if (feof(stdin)) 
    { 
     printf("Hit EOF on stdin; exiting\n"); 
     moreData = 0; 
    } 
    else if (ferror(stdin)) 
    { 
     /** 
     * I *think* scanf() sets errno; if not, replace 
     * the line below with a regular printf() and 
     * a generic "read error" message. 
     */ 
     perror("error during read"); 
     moreData = 0; 
    } 
    else 
    { 
     printf("Bad character stuck in input stream; clearing to end of line\n"); 
     while (getchar() != '\n') 
     ; /* empty loop */ 
     printf("Input no: "); 
     fflush(stdout); 
    } 
} 
+1

possibile ciclo infinito quando si cancella alla fine della riga. Suggerisco '' while (((ch = getchar())! = EOF) && (ch! = '\ N'))/* void * /; '' ad quindi controllando (di nuovo) per EOF e impostando '' moredata = 0; '' – pmg

+0

Si prega di aprire una nuova domanda. – andig

-2
while(scanf("%d %d",a,b)!=EOF) 
{ 

//do ..... 
} 
+0

ho usato questo ... –

+0

cosa non va:/non capisco –