Однак програмісти на C ++ зазначають, що завжди буває те, що cin.eof () не повертає "true" до того моменту, коли останній рядок буде прочитаний двічі.
Це не те, що відбувається. Не eofbitграє ніякої ролі в перетворенні на булеву ( stream::operator bool(або operator void*в старішій c ++)). Тільки badbitі failbitзаймаються.
Припустимо, ви читаєте файл, що містить числа, розділені пробілом. Петля, що базується навколо cin.eof(), неминуче буде або помилятися, або буде заповнена ifтестами. Ви не читаєте до EOF. Ви читаєте цифри. Тому зробіть свій код висловити цю логіку:
while (stream >> some_var) {
process_value(some_var);
}
Це буде працювати, чи закінчується останній рядок файлу 0 42\nабо просто 0 42(немає нового рядка в кінці останнього рядка у файлі). Якщо файл закінчується 0 42\n, останнє добре прочитання отримає значення 42 і прочитає цей кінцевий кінець маркера рядка. Зауважте, що маркер EOF ще не прочитаний. Функція process_valueвикликається за допомогою 42. Наступний виклик оператору витягування потоку >> зчитує EOF, і оскільки нічого не було вилучено, і eofbitі failbitбуде встановлено.
Припустимо, з іншого боку, файл закінчується на 0 42(немає нового рядка в кінці останнього рядка). Останнє добре прочитане отримає значення 42, що закінчується на маркері EOF. Імовірно, ви хочете обробити це 42. Ось чому eofbitне грає ролі в операторі булевого перетворення вхідного потоку. Під час наступного виклику оператору витягу потоку >> базовий апарат швидко бачить, що значення eofbitвже встановлено. Це швидко призводить до встановлення failbit.
Чому перший фрагмент коду завжди не працює належним чином?
Тому що ви не повинні перевіряти EOF як стан циклу. Умова циклу має виражати те, що ви намагаєтеся зробити, це (наприклад), витягування чисел із потоку.