14.6.3 管理流状态

    对流状态的管理可分为状态字的设置和缓冲区管理两部分,以下分别进行介绍。

    1.设置状态字

    ios_base类中提供了clear函数和setstate函数用来设置状态字。

    clear函数的原型如下所示。


    void ios_base:clear(int nState=0);

    如果参数为0,该函数将清除所有错误标志,否则,参数可以设置为goodbit、eofbit、failbit及badbit中的一种或者其共同的组合,clear函数首先将所有的标志清除,然后将参数指定的标志置位。

    setstate函数的原型如下所示。


    void ios_base:setstate(int nState);

    参数可以设置为eofbit、failbit及badbit中的一种或者其共同的组合,与clear函数不同,setstate函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。但需要注意的是如果nstate为goodbit,则setstate操作不会对流状态产生任何影响。

    具体来说,对状态字的设置可分为复位和置位两种具体操作。

    以输入流为例,如果流状态字中eofbit、failbit和badbit对应的位被置为1,说明输入流出了问题。此时,随后所有的输入操作都会被忽略,直到流状态字恢复正常,即为goodbit。使用程序设置流状态字的操作就是复位,使用无参clear函数便可很好地完成复位,如以下示例代码14.24所示。

    代码14.24 流状态字复位ResetState


    <————————————文件名:example1424.cpp———————————————> 01 #include<iostream> 02 using namespace std; 03 int main() 04 { 05 int x=0; 06 cin>>x; 07 cout<<x<<endl; 08 if(cin. fail())//如果匹配失败,输出信息 09 { 10 cout<<"匹配失败"<<endl; 11 } 12 //cin. clear(); 13 char y='x'; 14 cin>>y; 15 cout<<y<<endl; 16 return 0; 17 }

    输出结果如下所示。


    A 0 匹配失败 x

    【代码解析】先将代码第12行的语句“cin.clear();”注释起来,当用字符'A'给int型变量x赋值时,发生匹配错误,输入流将状态常量failbit对应的位置1,此时如果不加复位,随后的输入操作都被忽略,即便是留在缓冲区中的'A'可以和char型变量y匹配。

    为此,在代码14.24中加入语句“cin.clear()”,输出结果变为如下所示。


    A 0 匹配失败 A

    尽管对int型变量x的输入同样失败,但留在缓冲区中的字符'A'成功地赋值给了char型变量y。不仅仅需要复位,编程中根据需要可能会用到置位操作,用以通知输入输出流中出现的错误。

    2.管理缓冲区

    在某些情况下,仅仅将流状态字复位还不够,因为导致匹配失败和错误发生的输入仍残留在缓冲区中,程序必须将其从缓冲区中提取出来,跳过这些输入字符。解决的办法很多,前面介绍的诸如ignore函数和get函数等都可以满足要求。

    这里特别推荐一个sync函数,其调用格式如下所示。

    int sync()

    当同步成功,即数据被清除后返回0,发生错误时,返回EOF。

    C和C++标准输入输出缓冲区的清空方式如表14.9所示。

    14.6.3 管理流状态 - 图1