七、输入/输出流--IOStreamm基本类和标准IOStream对象--stream状态

来源:互联网 发布:手机fps游戏显示软件 编辑:程序博客网 时间:2024/06/11 08:17

3 stream状态

stream维持一种状态,如果状态是good,表示操作成功;
如果不是good,该流没有任何作用。

  • 状态为fail : 可以假设流未被破坏它,并且没有字符丢失;
  • 状态为bad: 意味着彻底失败。

3.1 stream状态常数

stream定义了一些型别为iostate的常数,来反应stream的状态。
1. iostate是class ios_base的成员;
2. 具体由实例版本确定;

iostate的常量包括:

  • goodbit : 一切都好
  • eofbit : 文件末尾标志
  • failbit : 错误,某个io操作未成功;
  • badbit : 毁灭性错误,不确定状态;

其中,badbit比failbit更严重:

  • failbit: 某项操作未完成,但是stream大体完成,即设立这个位;通常是由于读入格式错误,如程序需要读入整数,但是遇到字符;

  • badbit: 若stream由于不明原因而损坏或丢失数据,即设立这个位;例如某个stream被定为指向“文件起点”的更前方。

eofbit和failbit经常同时出现,在eof之后试图读取数据时,会检测到end-of-file状态。在读取最后一个字符时,eofbit未出现,再次试图读取的时候,eofbit和failbit同时被设置,因为读取操作失败了。

上述所有常数并非全局性,因此:需要添加域操作符,如:

std::ios_base::eofbit

使用ios_base的派生类也可以。通常以上标志类由base_ios维护,能够在basic_istream和basic_ostream的所有对象中使用。

3.2 stream状态相关成员函数

stream当前状态可以由一些成员函数来访问。包括:

  • good(): 若state正常,返回true;返回值类型为bool型;

  • eof() : 文件读取文件,遇到eof标志,返回true,表示eofbit被设置;

  • fail():若发生错误,表示failbit或者badbit被设置;

  • bad() : 发生毁灭性错误,返回true,此时badbit被设置;若rdstate()&badbit非零,函数返回1;

  • rdstate(): 返回当前已设置的所有标志;函数返回值类iostate类型;

  • clear() : 清除当前所有标志后;返回值为空;

  • setstate(state) : 设置state标志,返回值为空。实质是调用clear(_state|rdstate),state为要设置的标志位;

例子:

//-----------cout的状态--------------------    bool good = cout.good();    bool bad = cout.bad();    bool fail = cout.fail();    cout << "goodbit: " << good << endl;    cout << "badbit: " << bad << endl;    cout << "faildbit: " << fail << endl;    fstream fs;    bool eof = fs.eof();    cout << "eofbit: " << eof << endl;    ios_base::iostate rdstaste = cout.rdstate();    cout << "rdstate: " << rdstaste << endl;//-------------------------------结果为:goodbit: 1badbit: 0faildbit: 0eofbit: 0rdstate: 0

3.3 stream状态和异常

3.3.1 stream状态

多数情况下,stream不会抛出异常。标准化的stream允许对任何状态的标志进行定义,此状态标志被设置的时候,会引发异常。
异常处理机制包含了函数
- [exception()];
stream定义两个用于bool表达式的函数:

  • operator void*
  • !()
    这两个函数并不是显式的调用,而是隐含的调用;
    例如:
while(std::cin){}

结果中bool条件并不一定要转换我bool,只要能够转化为某个整数型或者指针型别就可以。
转换为void*,是为了在同一表达式中读入对象并测试是否成功。如:

if(std::cin>>x){}

此时,cin用于条件判断,cin调用operator void * ,返回“stream是否发生错误”。
通常,在while循环中,有时采用eof标志作为循环结束的条件,此时failbit和badbit均被设置。
使用“cin”操作符,默认情况下起头空格被跳过,但是如果从流中输入的是char,空格是有意义的。

使用operator!进行反相测试,会返回“stream是否发生错误”。此时标志位failbit和badbit被设置为true;

if(!std::cin>>x){}

[注]: 上述cin是stream对象,二用!cin时,描述cin状态的布尔值。

3.3.2 处理异常

调用exception时候,可以获得引发异常的标志。调用带参数的exception(),如果参数的标志被设置,会引发相应异常。函数原型为:

exception(flags) //设置“会引发异常”的标志exception() //返回引发异常的标志

说明 :
1. 函数的第二种形式: 如果返回的是goodbit,表示没有任何异常被抛出;
2. 函数第一种形式: 设置相应标志位,并引发相应异常。如果输入的是goodbit或者0,则不会引发异常。
3. 抛出异常: 是在“程序调用clear()或者setstate()之后”,设立该标志后,如果该标志已被设置并且未被清除,同样会抛出异常。抛出的异常是std::ios_base::failure对象,派生自exception类。

当获取错误信息时候,唯一可移植方式是借助函数what().只有函数what()有可移植性,what()的返回值不具有移植性。

例子:

//----------省略--------    ios_base::iostate  old = cin.exceptions();//获取异常    cout << "old exception: " << old << endl;    int x = 0;    try{        cin.exceptions(ios::eofbit | ios::failbit | ios::badbit);//设置标志位    //  cin.exceptions(ios::goodbit);        cin >> x;    }    catch (exception& e){//如果相应异常,就捕获        cout << "exceptions : " << e.what() << endl;    }//-----------省略-----------

需要输入一个整型值,但是我们输入一个字符,引发错误,结果为:

old exception: 0nexceptions : ios_base::failbit set: iostream stream error

如果设置标志位为goodbit或0,结果为:

old exception: 0n

不会捕捉到异常。


原创粉丝点击