Контроль операций обработки файлов заключается в проверке состояния потока (обнаружение ошибок) и,если возможно, восстановление потока (очистка ошибок). Рассмотрим средства, проверяющие операции открытия файла, чтения и записи.
Состояние потока оценивается битами класса ios:
goodbit - устанавливается, если операция прошла успешно;
eofbit - устанавливается, если больше нет символов для чтения, т.е. конец файла;
failbit - устанавливается, если операция чтения/записи закончилась с ошибкой; поток можно использовать после сброса бита;
badbit - устанавливается, если операция чтения/записи закончилась ошибкой; возможна потеря символов, но можно попробовать исправить, сбросив бит;
hardbit - устанавливается при неисправимой ошибке.
Восстановление потока,т.е. очистка битов ошибки, осуществляется функцией clear:
p.clear(n);, где n - либо код бита (0,1,2,4,8), либо его мнемоническое обозначение; при n=0 происходит очистка всех битов ошибок.
Состояние потока можно проверить различными способами. Проверка состояния потока с обнаружением конкретной ошибки выполняется функцией rdstate, которая возвращает код бита ошибки. Пример:
|
|
switch(p.rdstate()) //p - поток
{
case ios::goodbit: //операция успешна,продолжение программы
break;
case ios::eofbit: //конец файла, продолжение программы
break;
case ios::failbit: //ошибка, восстановление потока
break;
case ios::badbit: //ошибка, попытка восстановления потока
break;
case ios::hardbit: //неисправимая ошибка, выход из программы
break;
}
Альтернативным, вторым способом проверки состояния потока является использование функций класса ios:
good() - возвращает истину, если установлен goodbit (нет ошибок); возвращает ложь(ноль),если бит не установлен;
eof() - возвращает истину, если установлен eofbit (конец файла); возвращает ложь,если бит не установлен;
fail() - возвращает истину, если установлен failbit,badbit или hardbit; возвращает ложь,если биты не установлены;
bad() - возвращает истину, если установлен badbit или hardbit; возвращает ложь,если биты не установлены.
Примеры:
if (!p.good()) if (p.fail()) while(!p.eof())
{ { {
cerr<<"Ошибка..."; cerr<<"Ошибка..."; //нет конца файла
exit(-1); //выход exit(-1);//выход...
} } }
Удобен третий способ проверки состояния потока представлением имени потока или операции чтения/записи в виде логического выражения в операторах if, for, while, do-while.
Примеры:
if (p) if (!p)
{ {
//продолжение программы cerr<<"Ошибка...";
... exit(-1);//выход
} }
if (p.read((char*)&z,sizeof(z))) if(!p.read((char*)&z,sizeof(z)))
{ {
//продолжение программы cerr<<"Ошибка чтения...";
... exit(-1);//выход из программы
} }
Имя потока p и операция чтения p.read имеют значение не ноль (истинно), если нет ошибки, и ноль (ложно), если есть ошибка.