Stroustrup Принципы и практика программирования с использованием C ++ (2e, ch 10, print 6) дает следующую идиому - слегка измененную, чтобы сделать ее автономной и компилируемой - для итеративного чтения из входного потока до тех пор, пока не встретится EOF или назначенный символ-терминатор, за исключением исключения для любого другого условия остановки.
#include <iostream>
#include <stdexcept>
int main()
{
std::istream& is = std::cin;
char term = '|'; // terminator
for (int x; is >> x; ) {
// do something with x
}
if (is.bad()) {
throw std::runtime_error("bad input stream");
}
if (is.fail()) {
is.clear();
char c;
if (!(is >> c && c == term)) {
throw std::runtime_error("bad termination of input");
}
}
// carry on: we found EOF or terminator
}
Комментарии программы и окружающая экспозиция подразумевают, что EOF является приемлемым (не вызывающим ошибок) способом. для этого итеративного чтения до конца. Но когда я проверяю это на файлах, таких как следующий двухстрочный текстовый файл, не содержащий терминаторов,
3 1 4 1 5
9 2 6 5 3
выдается исключение («неправильное завершение ввода»). Исключением является то, что я ожидаю - после прочтения последнего «3» последующее чтение встречает EOF, вызывая переворачивание eofbit потока, но чтение также завершается неудачно, вызывая переворачивание failbit. Кажется, идиома предполагает, что eofbit и failbit являются взаимоисключающими.
Эта идиома исправна или имеет логическую ошибку в том, как обрабатывается случай EOF?