流状态的查询和控制

来源:互联网 发布:汽车保养提醒软件 编辑:程序博客网 时间:2024/05/16 02:36
 流有3个状态,对应于3个定义的位标志stream::iostate:


stream::badbit
系统级的故障,如无法恢复的读写错误,流通常无法继续使用。
stream::failbit
可恢复的流错误,如在希望获得数值型的数据时输入了字符,
stream::eofbit
文件结束,同时还会设置failbit标志
有3个操作bad(), fail(), eof()分别用于测试以上的标志,流状态是否正常可以用good()来测试;流的状态字可以由rdstate()读出;另外还有两个操作用于改变流的状态:clear()和setstate(),但它们的操作结果不怎么符合我们的直觉。


setstate必须有个一个表示流状态的参数,操作结果将使指定的状态位置位(set),其他的状态位不变,无法作reset操作。clear用于设置流的状态为参数指定的状态字,它实际上是个set操作,而不是reset,它的参数有一个默认的值为goodbit,这实际是个0,不带参数调用时就是clear状态,带参数时,并不是我们想象中的reset参数指定的位,而是将整个状态字设置成参数指定的那样。


说得有点罗嗦,请看basic_ios.h中的代码:


/*** g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) ***/
void clear(iostate __state = goodbit);
void setstate(iostate __state) {
    this->clear(this->rdstate() | __state;
}


C++Primer中文版的第4版,第8章,第2小节,(没有和C++ Primer英文版对应上),这里有一个例程:


int ival;
// Read cin and test only for EOF; loop is executed
// even if there are other IO failures.
while (cin >> ival, !cin.eof()) {   // input stream is corrupted; bail out
    if (cin.bad())
        throw runtime_error("IO Stream corrupted"); 
    if (cin.fail()) {                           // bad input
        cerr << "bad data, try again" << endl;  // warn the user
        cin.clear(istream::failbit);            // reset the stream
        break;
    }
    // ok to process ival
    cout << ival << endl;
}


这个循环不断读入cin,直到文件结束(eof: Ctrl+D)或者发生不可恢复的读取错误(bad),用户错误输入(输入字符而非数字, fail)时,打印错误提示并继续准备读取用户输入。


这里对clear的用法是错误的,根据上面的说明,clear(istream::failbit)并不能reset这个failbit,而是使整个状态字只有failbit置位,while将陷入死循环。正确的做法应该如下:


cin.clear(istream::failbit ^ cin.rdstate());
0 0
原创粉丝点击