Jednak programiści C ++ zauważają, że zawsze zdarza się, że cin.eof () nie zwraca „true”, dopóki podwójny odczyt nie zostanie odczytany.
Tak się nie dzieje. Nie eofbitodgrywa żadnej roli w konwersji na wartość logiczną ( stream::operator bool(lub operator void*starszą wersję c ++)). Zaangażowani są tylko badbiti failbit.
Załóżmy, że czytasz plik zawierający liczby oddzielone spacjami. Pętla oparta na niej cin.eof()nieuchronnie będzie albo błędna, albo będzie pełna iftestów. Nie czytasz do EOF. Czytasz cyfry. Niech twój kod wyrazi tę logikę:
while (stream >> some_var) {
process_value(some_var);
}
Działa to niezależnie od tego, czy ostatni wiersz pliku kończy się na, 0 42\nczy tylko 0 42(nie ma nowego wiersza na końcu ostatniego wiersza w pliku). Jeśli plik kończy się na 0 42\n, ostatni dobry odczyt pobierze wartość 42 i odczyta znacznik końca linii. Zauważ, że znacznik EOF nie został jeszcze odczytany. Funkcja process_valuejest wywoływana za pomocą 42. Następne wywołanie do operatora ekstrakcji strumienia >> czyta EOF, a ponieważ nic nie zostało wyodrębnione, ustawione zostaną zarówno eofbiti failbit.
Załóżmy z drugiej strony, że plik kończy się na 0 42(brak nowej linii na końcu ostatniego wiersza). Ostatni dobry odczyt odzyska wartość 42 kończącą się na znaczniku EOF. Prawdopodobnie chcesz to przetworzyć 42. To dlatego eofbitnie odgrywa roli w operatorze konwersji wartości logicznej strumienia wejściowego. Przy następnym wywołaniu do operatora wydobycia strumienia >> maszyna leżąca pod spodem szybko zauważy, że eofbitjest już ustawiony. To szybko powoduje ustawienie failbit.
Dlaczego pierwszy fragment kodu zawsze nie działa poprawnie?
Ponieważ nie powinieneś sprawdzać EOF jako warunku pętli. Warunek pętli powinien wyrażać to, co próbujesz zrobić, czyli (na przykład) wyodrębnianie liczb ze strumienia.