logo
шпоры по ООП

44.Обработка ошибок в потоке через определение и установку состояния потока.

У любого потока есть набор флагов, с помощью которых можно следить за состоянием потока. Имеются четыре предикатные функции-члена:

eof() возвращает true, если достигнут конец файла:

if ( inOut.eof() )

// отлично: все прочитано ...

bad() возвращает true при попытке выполнения некорректной операции, например при установке позиции за концом файла. Обычно это свидетельствует о том, что поток находится в состоянии ошибки;

fail() возвращает true, если операция завершилась неудачно, например не удалось открыть файл или передан некорректный формат ввода:

ifstream iFile( filename, ios_base::in );

if ( iFile.fail() ) // не удалось открыть

error_message( ... );

good() возвращает true, если все вышеперечисленные условия ложны:

if ( inOut.good() )

Существует два способа явно изменить состояние потока iostream. С помощью функции-члена clear() ему явно присваивается указанное значение. Функция setstate() не сбрасывает состояние, а устанавливает один из флагов, не меняя значения остальных. Например, в коде оператора ввода для класса WordCount при обнаружении неверного формата мы используем setstate() для установки флага fail в состоянии объекта istream:

if ((ch = is.get()) != '<' )

{

is.setstate( ios_base::failbit );

return is;

}

Имеются следующие значения флагов состояния:

ios_base::badbit

ios_base::eofbit

ios_base::failbit

ios_base::goodbit

Для установки сразу нескольких флагов используется побитовый оператор ИЛИ:

is.setstate( ios_base::badbit | ios_base::failbit );

При тестировании оператора ввода в классе WordCount (см. раздел 20.5) мы писали:

if ( !cin ) {

cerr << "Ошибка ввода WordCount" << endl;

return -1;

}

Возможно, вместо этого мы предпочли бы продолжить выполнение программы, предупредив пользователя об ошибке и попросив повторить ввод. Но перед чтением нового значения из потока cin необходимо перевести его в нормальное состояние. Это можно сделать с помощью функции-члена clear():

cin.clear(); // сброс ошибок

В более общем случае clear() используется для сброса текущего состояния и установки одного или нескольких флагов нового. Например:

cin.clear( ios_base::goodbit );

восстанавливает нормальное состояние потока. (Оба вызова эквивалентны, поскольку goodbit является для clear() аргументом по умолчанию.)

Функция-член rdstate() позволяет получить текущее состояние объекта:

ios_base::iostate old_state = cin.rdstate();

cin.clear();

process_input();

// перевести поток cin в прежнее состояние

cin.clear( old_state );