注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

长风明志的博客

不要也不能做下一个谁,应该且可以做第一个自己

 
 
 

日志

 
 

C++中io库的setstate和clear区别  

2012-10-30 14:21:32|  分类: C/C++编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

来看看输入状态标记位、状态测试函数、状态设置函数之间的关系:

  输入状态标记位常量有以下几个:

标记位常量

常量

含义

failbit标记位的值

eofbit标记位的值

badbit标记位的值

转化为10进制

ios::failbit

输入(输出)流出现非致命错误,可挽回

1

0

0

4

ios::badbit

输入(输出)流出现致命错误,不可挽回

0

0

1

2

ios::eofbit

已经到达文件尾

0

1

0

1

ios::goodbit

流状态完全正常

0

0

0

0


  下面来解释这张表格:

  ios::failbit    ios::badbit    ios::eofbit    ios::goodbit均为常量,它们任何一个都代表了一种流状态,因此称为“输入状态标记位常量”。

  比如,ios::failbit表示的是流状态为

  流的failbit标记位值为1,eofbit标记位值为0,badbit标记位的值为0。

  始终牢记:failbit,badbit,Eofbit组成了流状态

  注意:它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量。

  我们可以用输出语句来验证:

  cout << ios:: failbit << endl;

  cout << ios:: eofbit << endl;

  cout << ios:: badbit << endl;

  cout << ios:: goodbit << endl;

  输出的结果为:

  4

  2

  1

  0

  同样是将3个标记位视为二进制数转化为十进制的原理。

  下面分析clear()函数:

  cin.clear(ios::failbit);

  使 得cin的流状态将按照ios::failbit所描述的样子进行设置:failbit标记位为1,eofbit标记位为0,badbit标记位为0。无 需担心goodbit标记位,failbit、eofbit、badbit任何一个为1,则goodbit为0。(goodbit是另一种流状态的表示方 法)

  cin.clear(ios::goodbit);

  使得cin的流状态将按照ios::goodbit所描述的样子进行设置:failbit标记位为0,eofbit标记位为0,badbit标记位为0。此时goodbit标记位为1,从另一个角度表示cin的流状态正常。

  因此clear() 函数作用是:将流状态设置成括号内参数所代表的状态,强制覆盖掉流的原状态。

  再来分析一下setstate()函数:

  与clear()函数不同,setstate()函数并不强制覆盖流的原状态,而是将括号内参数所代表的状态叠加到原始状态上。

  比如,假设cin流状态初始正常:

  cin.setstate (ios::failbit);      //在cin流的原状态的基础上将failbit标记位置为1

  cin.setstate (ios::eofbit);     //在上一步结束的基础上,将cin流状态的eofbit标记位置为1

  两条语句结束后,cin的faibit标记位和eofbit标记位均为1,badbit标记位为0

  对比clear()函数的效果:

  cin.clear (ios::failbit);      //将cin的流状态置为ios::failbit所描述的状态

  cin.clear (ios::eofbit);     //将cin的流状态置为ios::eofbit所描述的状态

  两条语句结束后,cin的eofbit标记位为1,而failbit标记位和badbit标记位为0

  即使两种情况,在执行完各自的第一条语句后,cin的流状态情况相同,但当执行完第二条语句,本质区别就显露出来。

最后来看看如何利用rdstate()函数和输入状态标记位常量来判断输入流的状态:

  #include <iostream>

  using namespace std;

  int main()

  {

  int a;

  cin>>a;

  cout<<cin.rdstate()<<endl;

  if(cin.rdstate() == ios::goodbit)

  {

  cout<<"输入数据的类型正确,无错误!"<<endl;

  }

  if(cin.rdstate() == ios::failbit)

  {

  cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;

  }

  system("pause");

  return 0;

  }

  利用前面所讲的rdstate() 函数返回值原理和输入状态标记位常量表,不难理解:

  rdstate() 函数返回当前流对象的failbit、eofbit、badbit3个标记位状态的十进制值

  输入状态格式常量也是failbit、eofbit、badbit3个标记位状态的十进制值

  比如cin流状态读取错误,即failbit标记位为1,eofbit标记位为0,badbit标记位为0,则:

  cin.rdstate()的返回值为4,而格式常量ios::failbit的十进制也是4

  因此,if(cin.rdstate() == ios::failbit) 判断为Ture

  因此程序当中的两个if语句能有效识别出流状态

  再来看看有些许不同的程序:

  #include <iostream>

  using namespace std;

  int main()

  {

  cin.setstate(ios::failbit);

  cin.setstate(ios::eofbit);

  cout<<cin.rdstate()<<endl;

  if(cin.rdstate() == ios::goodbit)

  {

  cout<<"输入数据的类型正确,无错误!"<<endl;

  }

  if(cin.rdstate() == ios::failbit)

  {

  cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;

  }

  system("pause");

  return 0;

  }

  输出结果为:

  6

  请按任意键继续...

  原因为何?

  cin流状态被设置成failbit标记位置为1,eofbit标记位置为1,badbit标记位为0

  那么cin.rdstate()的返回值二进制为110,十进制为6,即输出6。

  参照输入状态标记位常量表:

  ios::goodbit的二进制为000,十进制为0,因此if(cin.rdstate() == ios::goodbit)判断为False

  ios::failbit的二进制为100,十进制为4,因此if(cin.rdstate() == ios::failbit)判断为False

  然后system("pause"); 语句使得输出         请按任意键继续...

  很有意思吧,cin对象明明failbit标记位为1,但表达式cin.rdstate() == ios::failbit却是False,这就是原因。

  rdstate()函数与输入状态标记位常量的对比是严格按照数值对比的。

  评论这张
 
阅读(656)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017