9.7 流错误的处理
在对流进行操作时,特别是用流读写磁盘文件时,可能会发生错误。因此,必须有一种能够检测到错误状态的机制和清除错误的方法。例如,在打开一个文件时,若找不到这个文件或发生其他错误,就需要处理错误状态,使得流能够恢复正常处理。
9.7.1 状态字和状态函数
流对象的状态由一个状态字来记录,它用来表示各种错误或状态。状态字中的各位由 ios
类中定义的下述常量来描述:
goodbit = 0x00 // 表示状态正常,没有位设置
eofbit = 0x01 // 表示到达文件末尾
failbit = 0x02 // 表示 I/O 操作失败
badbit = 0x04 // 表示试图进行非法操作
hardbit = 0x80 // 表示致命错误
其中,failbit
位设置表示流没有受到破坏,可以恢复。如果 hardbit
位设置表示设备硬件故障而不可恢复,则使用 clear()
函数可以清除除了 hardbit
以外的其他错误所设置的位。
在 ios
类中还定义了检测流状态的下列各个成员函数:
int rdstate(); // 返回当前状态字
int eof(); // 返回非零值表示提取操作已到文件尾
int fail(); // 返回非零值表示 I/O 操作失败
int bad(); // 返回非零值表示试图进行非法操作
int good(); // 返回非零值表示状态正常
可以利用上述函数来检测流是否出错。例如:
ifstream ist("t.dat");
if (ist.good()) {
// 文件打开成功,进行某些操作
}
又如:
ifstream ist("t2.dat");
if (!ist.good()) {
// 文件没有被打开,退出该程序
}
此外,由于 ios
类中定义了如下成员函数:
int ios::operator!();
因此可以直接用下述方法判断流状态是否正常:
ifstream istrm("f.dat");
if (!istrm) {
cout << "f.dat can't open.\n";
}
9.7.2 清除和设置流的状态位
ios
类中定义了下述成员函数:
void ios::clear(int = 0);
用来清除和设置流的状态位,但它不能设置和清除 hardbit
位。该函数更多用于当流发生错误时清除流的错误状态,这时使用不带参数的 clear()
函数。有时也可以用来设置流的状态错误,这时使用带参数的 clear()
函数。例如:
cin.clear(cin.rdstate() | ios::badbit); // 设置 badbit 位
cin.clear(); // 清除除了 hardbit 以外的其他流中的错误
[例 9.31] 下面是一个测试流对象 cin
的错误状态位的程序。分析该程序的输出结果。
程序内容如下:
#include <iostream.h>
void main() {
int a;
cout << "Enter an integer: ";
cin >> a;
cout << "cin.rdstate(): " << cin.rdstate() << endl
<< "cin.eof(): " << cin.eof() << endl
<< "cin.bad(): " << cin.bad() << endl
<< "cin.fail(): " << cin.fail() << endl
<< "cin.good(): " << cin.good() << endl;
cout << "Enter a character: ";
int b;
cin >> b;
cout << "cin.rdstate(): " << cin.rdstate() << endl
<< "cin.eof(): " << cin.eof() << endl
<< "cin.bad(): " << cin.bad() << endl
<< "cin.fail(): " << cin.fail() << endl
<< "cin.good(): " << cin.good() << endl;
cin.clear();
cout << "After clear, cin.good(): " << cin.good() << endl;
cin.clear(ios::failbit);
cout << "After setting failbit, cin.good(): " << cin.good() << endl;
}
执行该程序后,输出如下信息:
Enter an integer: 89
cin.rdstate(): 0
cin.eof(): 0
cin.bad(): 0
cin.fail(): 0
cin.good(): 1
Enter a character: p
cin.rdstate(): 2
cin.eof(): 0
cin.bad(): 0
cin.fail(): 2
cin.good(): 0
After clear, cin.good(): 1
After setting failbit, cin.good(): 0
说明:
- 该程序先输入一个
int
型数给变量a
赋值,此时测试状态位都无错。cin.good()
为 1 表示无错。 - 再输入一个字符给
int
型变量b
赋值,此时状态位failbit
被置为 1,表示 I/O 错误。状态字rdstate()
为 2,goodbit
为 0。 - 经过调用
clear()
清除错误状态位后,goodbit
为 1。再设置failbit
错误后,goodbit
又为 0。
可以将程序中的 int b;
改写为:
char b;
再按上述输入观察输出结果有何变化,并思考为什么。