条件状态
实现 IO 的继承正是错误发生的根源。一些错误是可恢复的;一些错误则发生在系统底层,位于程序可修正的范围之外。IO 标准库管理一系列条件状态(condition state) 成员,用来标记给定的 IO 对象是否处于可用状态,或者碰到了哪种特定的错误。
|
strm::iostate |
机器相关的整型名,由各个 iostream 类定义,用于定义条件状态 |
|
strm::badbit |
strm::iostate 类型的值,用于指出被破坏的流 |
|
strm::failbit |
strm::iostate 类型的值,用于指出失败的 IO 操作 |
|
strm::eofbit |
strm::iostate 类型的值,用于指出流已经到达文件结束符 |
|
s.eof() |
如果设置了流 s 的 eofbit 值,则该函数返回 true |
|
s.fail() |
如果设置了流 s 的 failbit 值,则该函数返回 true |
|
s.bad() |
如果设置了流 s 的 badbit 值,则该函数返回 true |
|
s.good() |
如果流 s 处于有效状态,则该函数返回 true |
|
s.clear() |
将流 s 中的所有状态值都重设为有效状态 |
|
s.clear(flag) |
将流 s 中的某个指定条件状态设置为有效。flag 的类型是strm::iostate |
|
s.setstate(flag) |
给流 s 添加指定条件。flag 的类型是 strm::iostate |
|
s.rdstate() |
返回流 s 的当前条件,返回值类型为 strm::iostate |
考虑下面 IO 错误的例子:
int ival;
cin >> ival;
如果在标准输入设备输入 Borges,则 cin 在尝试将输入的字符串读为 int型数据失败后,会生成一个错误状态。类似地,如果输入文件结束符(end-of-file),cin 也会进入错误状态。而如果输入 1024,则成功读取,cin将处于正确的无错误状态。
流必须处于无错误状态,才能用于输入或输出。检测流是否用的最简单的方法是检查其真值:
if (cin)
// ok to use cin, it is in a valid state
while (cin >> word)
// ok: read operation successful ...
if 语句直接检查流的状态,而 while 语句则检测条件表达式返回的流,从而间接地检查了流的状态。如果成功输入,则条件检测为 true。
条件状态
许多程序只需知道是否有效。而某些程序则需要更详细地访问或控制流的状态,此时,除了知道流处于错误状态外,还必须了解它遇到了哪种类型的错误。
所有流对象都包含一个条件状态成员,该成员由 setstate 和 clear 操作管理。这个状态成员为 iostate 类型,这是由各个 iostream 类分别定义的机器相关的整型。该状态成员以二进制位(bit)的形式使用。
badbit 标志着系统级的故障,如无法恢复的读写错误。如果出现了这类错误,则该流通常就不能再继续使用了。如果出现的是可恢复的错误,如在希望获得数值型数据时输入了字符, 此时则设置 failbit 标志, 这种导致设置 failbit的问题通常是可以修正的。eofbit 是在遇到文件结束符时设置的,此时同时还设置了 failbit。
流的状态由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof中的任意一个为 true,则检查流本身将显示该流处于错误状态。类似地,如果这三个条件没有一个为 true,则 good 操作将返回 true。
clear 和 setstate 操作用于改变条件成员的状态。clear 操作将条件重设为有效状态。在流的使用出现了问题并做出补救后,如果我们希望把流重设为有效状态,则可以调用 clear 操作。使用 setstate 操作可打开某个指定的条件,用于表示某个问题的发生。除了添加的标记状态,setstate 将保留其他已存在的状态变量不变。
流状态的查询和控制
可以如下管理输入操作:
int ival;
// read cin and test only for EOF; loop is executed even if there ar
other IO failures
while (cin >> ival, !cin.eof()) {
if (cin.bad()) // input stream is corrupted; bail ou
throw runtime_error("IO stream corrupted");
if (cin.fail()) { // bad input
cerr<< "bad data, try again"; // warn the user
cin.clear(istream::failbit); // reset the stream
continue; // get next input
}
// ok to process ival
}
这个循环不断读入 cin,直到到达文件结束符或者发生不可恢复的读取错误为止。
在循环中,首先检查流是否已破坏。如果是的放,抛出异常并退出循环。如果输入无效,则输出警告并清除 failbit 状态。
条件状态的访问
rdstate 成员函数返回一个 iostate 类型值,该值对应于流当前的整个条件状态:
// remember current state of cin
istream::iostate old_state = cin.rdstate();
cin.clear();
process_input(); // use cin
cin.clear(old_state); // now reset cin to old state
多种状态的处理
常常会出现需要设置或清除多个状态二进制位的情况。此时,可以通过多次调用 setstate 或者 clear 函数实现。另外一种方法则是使用按位或(OR)操作符在一次调用中生成“传递两个或更多状态位”的值。按位或操作使用其操作数的二进制位模式产生一个整型数值。对于结果中的每一个二进制位, 如果其值为 1, 则该操作的两个操作数中至少有一个的对应二进制位是 1。例如:
// sets both the badbit and the failbit
is.setstate(ifstream::badbit | ifstream::failbit);
将对象 is 的 failbit 和 badbit 位同时打开。实参:
is.badbit | is.failbit
生成了一个值,其对应于 badbit 和 failbit 的位都打开了,也就是将这两个位都设置为 1,该值的其他位则都为 0。在调用 setstate 时,使用这个值来开启流条件状态成员中对应的 badbit 和 failbit 位。

浙公网安备 33010602011771号