However, C++ programmers note that what always happens is that cin.eof() doesn't return "true" until after the last line has been read twice.
Questo non è ciò che sta accadendo. eofbit
non ha alcun ruolo nella conversione in un valore booleano ( stream::operator bool
(o operator void*
nel vecchio c ++)). Sono coinvolti solo badbit
e failbit
.
Supponiamo di leggere un file contenente numeri separati da spazi bianchi. Un loop basato su cin.eof()
sarà inevitabilmente sbagliato o pieno zeppo di if
test. Non stai leggendo fino all'EOF. Stai leggendo i numeri Quindi fai in modo che il tuo codice esprima quella logica:
while (stream >> some_var) {
process_value(some_var);
}
Funzionerà se l'ultima riga del file termina con 0 42\n
o solo 0 42
(nessuna nuova riga alla fine dell'ultima riga nel file). Se il file termina con 0 42\n
, l'ultima lettura buona recupererà il valore 42 e leggerà quell'indicatore finale di fine riga. Si noti che l'indicatore EOF non è ancora stato letto. La funzione process_value
è chiamata con 42
. La prossima chiamata all'operatore di estrazione del flusso > > legge EOF e poiché non è stato estratto nulla, verranno impostati sia eofbit
che failbit
.
Supponiamo d'altra parte che il file termini con 0 42
(nessuna nuova riga alla fine dell'ultima riga). L'ultima buona lettura recupererà il valore 42 che termina sul marcatore EOF. Presumibilmente si desidera elaborarlo 42. Questo è il motivo per cui eofbit
non ha alcun ruolo nell'operatore di conversione booleana del flusso di input. Alla prossima chiamata all'operatore di estrazione stream > & gt ;, il macchinario sottostante vede rapidamente che eofbit
è già impostato. Ciò comporta rapidamente l'impostazione di failbit
.
Why does the first piece of code always fail to work properly?
Perché non dovresti controllare EOF come condizione del ciclo. La condizione del ciclo dovrebbe esprimere quello che stai cercando di fare, che è (per esempio), estrarre numeri da uno stream.