Состояние потока

Потоки istream или ostream имеют связанное с ними состояние. В классе ios, базовом для классов istream и ostream, имеется несколько public-функций, позволяющих проверять и устанавливать состояние потока:

inline int ios::bad() const { return state & badbit; }

inline int ios::eof() const { return state & eofbit; }

inline int ios::fail() const { return state & (badbit | failbit); }

inline int ios::good() const { return state == 0; }

Состояние потока фиксируется в элементах перечисления, объявленного в классе ios:

public:

enum io_state { goodbit = 0x00,

eofbit = 0x01,

failbit = 0x02,

badbit = 0x04 };

Состояние потока принимает значение goodbit или eofbit, если последняя операция ввода прошла успешно. Если состояние goodbit, то следующая операция ввода может пройти успешно. Состояние потока принимает значение eofbit, если при вводе встречен признак конца файла. Отличие между состояниями failbit и badbit очень незначительно. В состоянии failbit предполагается, что в потоке происходит ошибка форматирования, но поток не испорчен и символы в потоке не потеряны. В состоянии badbit может быть все что угодно.

Кроме отмеченных выше функций в классе ios есть еще несколько функций, позволяющих прочитать (rdstate) и очистить (clear) состояние потока:

inline int ios::rdstate() const { return state; }

inline void ios::clear(int _i=0){ lock(); state = _i; unlock(); }

Так, если было установлено состояние ошибки, то попытка выполнить ввод/вывод будет игнорироваться до тех пор, пока не будет устранена причина ошибки и биты ошибки не будут сброшены функцией clear().

#include <iostream>

using namespace std;

int main()

{ int i, flags;

char c;

do{ cin >> i;

flags=cin.rdstate(); // чтение состояния потока cin

if(flags & ios::failbit)

{ cout << "error in stream"<< endl;

cin.clear(0); // сброс всех состояний потока

cin>>c; // удаление не int значения из потока

}

else cout << i<<endl;

} while(flags); // пока ошибка во входном потоке

return 0;

}

В приведенном примере функция cin.clear(0) выполняет сброс всех установленных бит ошибки. Если требуется сбросить, например, только badbit, то clear(ios::badbit). На примере ниже показано, что состояние потока может быть проанализировано также при работе с файлами.

#include <fstream>

#include <iostream>

using namespace std;

int main()

{ ifstream in("file");

int state;

char ss[10];

while(1)

{ state=in.rdstate(); // чтение состояния потока in (файла)

if (state) // ошибка в потоке

{ if(state&ios::badbit) cout<<"ошибка открытия файла"<<endl;

else if(state&ios::eofbit) cout<<"в файле больше нет данных"<<endl;

return 0;

}

else in >> ss;

}

}

Необходимо также отметить, что в классе ios выполнена перегрузка операции ! :

inline int ios::operator!() const { return state&(badbit|failbit); }

то есть операция ! возвращает ненулевое значение в случае установки одного из бит badbit или failbit, иначе нулевое значение, например:

if(!cin) cout << ”ошибка потока cin”<<endl; // проверка состояния

else cin>>i; // входного потока

Наши рекомендации