在C++的标准IO库中,指定了一些方法来管理缓冲区及其流的状态。虽然很多程序只需要知道流是否有效即可,但是,不排除某些程序需要更详细地访问或者控制流的状态,以及当流出现错误的时候需要弄清楚具体是哪方面的错误。
首先,标准IO库用一个枚举来定义了流对象的四种状态:
enum _Iostate{ goodbit = 0x0, //正常可用状态 eofbit = 0x1, //遇到文件结束符的状态 failbit = 0x2, //读入错误数据的状态(可恢复) badbit = 0x4, //出现系统故障的读写错误状态(无法回复) _Statmask = 0x7}; };
当用相应的函数来返回流对象的当前状态,则会输出上面四种状态值其中的一种。如下程序:
<span style="white-space:pre"> </span>int i; cout<<"please enter the i value: "; cin>>i; cout<<cin.rdstate()<<endl; //返回流对象当前的状态值当输入的值为int型时,结果如下:
可以看出当输入的值是符合i的定义类型时,输出的流对象cin的状态值是0,0对应的状态是goobit;
当输入的值为string型时,结果如下:
可以看出当输入的值不符合i的定义类型时,输出的流对象cin的状态值是2,2对应的状态是failbit;
对应的有四种操作来反映流对象是否处于其中的某种状态:bool good(); //如果处于正常可用状态则返回true bool eof(); //如果遇到文件结束符则返回true bool fail(); //如果读入错误数据则返回true bool bad(); //如果出现系统故障则返回true
还有一些函数来对流对象的条件状态进行手动设置,如下:
clear(); //将流对象的所有状态值设置为有效状态 clear(flag); //将流对象的某个指定条件状态设置为有效 setstate(flag); //给流对象添加指定条件 rdstate(); //返回流对象的当前状态举个例子说明一下,如下程序:
int i; cout<<"please enter the i value: "; cin>>i; // cout<<cin.rdstate()<<endl; //返回流对象当前的状态值 cout<<"before clear the states: "<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; cin.clear(); cout<<"after clear the states: "<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl;运行结果如下:
如图,当输入的类型是string时,则cin对象的当前状态值为failbit,则good()、eof()、bad()的三个函数的返回值将为false,而fail()函数的返回值则为true。当将cin的状态被clear重新设置为有效后,则cin对象的当前状态重置为goodbit,即good()将返回true,其它的三个函数将返回false。
手动设置某个条件状态有效则用clear(flag)函数,如下:
int i; cout<<"please enter the i value: "; cin>>i; // cout<<cin.rdstate()<<endl; //返回流对象当前的状态值 cout<<"before clear the states: "<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; cin.clear(); cout<<"after clear the states: "<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl; cin.clear(cin.failbit); cout<<"set the failbit to true: "<<cin.good()<<cin.eof()<<cin.fail()<<cin.bad()<<endl;运行结果如下:
小结:每个流对象在某个时刻总是会处于某种状态,这种状态可能是goodbit、badbit、failbit、eofbit等,我们可以用rdstate()函数来返回该流对象当前的状态值。然后我们可以用good()、eof()、bad()和fail()等函数来测试该流对象是否处在某个特定状态,是则返回true,否则返回false。然后我们还可以用clear()和clear(flag)函数来对该流对象的某个状态进行手动更改。