out2 = print(out2); // ошибка: нельзя копировать потоковые объекты

Поскольку объекты типа ввода-вывода нельзя копировать, не может быть параметра или типа возвращаемого значения одного из потоковых типов (см. раздел 6.2.1). Функции, осуществляющие ввод-вывод, получают и возвращают поток через ссылки. Чтение или запись в объект ввода-вывода изменяет его состояние, поэтому ссылка не должна быть константой.

<p>8.1.2. Флаги состояния</p>

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

Таблица 8.2. Флаги состояния библиотеки ввода-вывода

strm::iostatestrm — один из типов ввода-вывода, перечисленных в табл. 8.1. iostate — машинно-зависимый целочисленный тип, представляющий флаг состояния потока
strm::badbitЗначение флага strm::iostate указывает, что поток недопустим
strm::failbitЗначение флага strm::iostate указывает, что операция ввода- вывода закончилась неудачей
strm::eofbitЗначение флага strm::iostate указывает, что поток достиг конца файла
strm::goodbitЗначение флага strm::iostate указывает, что поток не находится в недопустимом состоянии. Это значение гарантированно будет нулевым
s.eof()Возвращает значение true, если для потока s установлен флаг eofbit
s.fail()Возвращает значение true, если для потока s установлен флаг failbit
s.bad()Возвращает значение true, если для потока s установлен флаг badbit
s.good()Возвращает значение true, если поток s находится в допустимом состоянии
s.clear()Возвращает все флаги потока s в допустимое состояние
s.clear(флаг)Устанавливает определенный флаг (флаги) потока s в допустимое состояние. Флаг имеет тип strm::iostate
s.setstate(флаг)Добавляет в поток s определенный флаг. Флаг имеет тип strm::iostate
s.rdstate()Возвращает текущее состояние потока s как значение типа strm::iostate

В качестве примера ошибки ввода-вывода рассмотрим следующий код:

int ival;

cin >> ival;

Если со стандартного устройства ввода ввести, например, слово Boo, то операция чтения потерпит неудачу. Оператор ввода ожидал значение типа int, но получил вместо этого символ В. В результате объект cin перешел в состояние ошибки. Точно так же объект cin окажется в состоянии ошибки, если ввести символ конца файла.

Как только произошла ошибка, последующие операции ввода-вывода в этом потоке будут терпеть неудачу. Читать или писать в поток можно только тогда, когда он находится в неошибочном состоянии. Поскольку поток может оказаться в ошибочном состоянии, код должен проверять его, прежде чем использовать. Проще всего определить состояние потокового объекта — это использовать его в условии:

while (cin >> word)

 // ok: операция чтения успешна ...

Условие оператора while проверяет состояние потока, возвращаемого выражением >>. Если данная операция ввода успешна, состояние остается допустимым и условие выполняется.

Опрос состояния потока

Использование потока в условии позволяет узнать только то, допустим ли он. Это ничего не говорит о случившемся. Иногда необходимо также узнать причину недопустимости потока. Например, действия после достижения конца файла, вероятно, будут отличаться от таковых после ошибки на устройстве ввода-вывода.

Перейти на страницу:

Похожие книги