Программирование. Принципы и практика использования C++ Исправленное издание, стр. 143
// стоп! if (ist.fail()) { // очищаем путаницу как можем и сообщаем // об ошибке ist.clear(); // очищаем состояние потока // и теперь снова можем искать признак // завершения char c; ist>>c; // считываем символ, возможно, признак // завершения if (c != terminator) { // неожиданный символ ist.unget(); // возвращаем этот символ назад ist.clear(ios_base::failbit); // переводим поток // в состояние fail() } }}Обратите внимание на то, что пока мы не найдем признак конца файла, мы не выйдем из цикла. Кроме того, мы можем собрать некоторые данные, и функция, вызвавшая функцию
fill_vector()fail()fail()ist.clear(ios_base::failbit)clear()clear()iostreamfail()istunget()fill_vector()unget()putback()Если вы вызвали функцию
fill_vector()fail()eof()runtime_errorerror()istreambad()bad()
istream// поток ist генерирует исключение, если попадает в состояние badist.exceptions(ist.exceptions()|ios_base::badbit);Эти обозначения могут показаться странными, но результат простой: если поток
istbad()ios_base::failureexceptions()bad()void fill_vector(istream& ist, vector<int>& v, char terminator) // считываем целые числа из потока ist в вектор v, пока не // достигнем конца файла eof() или признака завершения{ int i = 0; while (ist >> i) v.push_back(i); if (ist.eof()) return; // отлично: обнаружен конец файла // не good(), не bad() и не eof(), // поток ist должен быть переведен в состояние fail() ist.clear(); // сбрасываем состояние потока char c; ist>>c; // считываем символ в поисках признака завершения ввода if (c != terminator) { // Ох: это не признак завершения ввода, // значит, нужно вызывать функцию fail() ist.unget(); // может быть, вызывающая функция // может использовать этот символ ist.clear(ios_base::failbit); // установить состояние fail() }}Класс
ios_baseiostreambadbitfailure::ios_base::badbitiostream;iostreamiostream,