cin.clear()

zhulinjia 2008-06-30 12:44:13
cin.clear() 将流cin中的所有状态值都重设为有效状态.

不懂这句是什么意思.
...全文
2579 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Sunsy 2012-08-08
  • 打赏
  • 举报
回复
总结不错
lhbaiya 2012-05-13
  • 打赏
  • 举报
回复
受教了...
howard986 2012-04-21
  • 打赏
  • 举报
回复
总结不错
bestwaqh 2010-04-09
  • 打赏
  • 举报
回复
学习了。。。
clhposs 2008-06-30
  • 打赏
  • 举报
回复
流出现错误就恢复

不管是遇到文件结束符还是别的错误

cin.clear()都解决 嘎嘎!
tangshuiling 2008-06-30
  • 打赏
  • 举报
回复
踏个脚印
matrixdwy 2008-06-30
  • 打赏
  • 举报
回复
cin的状态位有四个
ios::failbit
ios::badbit
ios::eofbit
ios::goodbit
goodbit说明当前流状态良好
而badbit说明发生了不可修复的错误,应该终止程序
cin.clear()就是将其他两个状态位统统归位为goodbit
状态位的设置用的是cin.setstate()
K行天下 2008-06-30
  • 打赏
  • 举报
回复
下面是我博客里的内容:


cin的总结
近日浏览CSDN,发现经常会有关于cin的问题

参考文献:

http://blog.csdn.net/daineng/archive/2008/04/05/2252730.aspx

http://www.augustcouncil.com/~tgibson/tutorial/iotips.html

http://hi.baidu.com/bdruiruili/blog/item/5966d9958a6eb20c7bf4801f.html

http://www.cplusplus.com/reference/iostream/istream/



建议看看:Tips and Tricks for Using C++ I/O (input/output)

在cin>><int/float/double>时 如果我们输入一个字符,就会导致刷屏的结果。这是因为非数字字符无法被cin接收而一直停留在输入缓冲区,从而导致下一次cin时直接从缓冲区中读取数据,但是字符无法读取,导致死循环。

那么怎么解决呢?

第一、 在cin>><int/float/double>后加cin.ignore(); cin.clear();

第二、 在cin>><int/float/double >后加fflush(stdin); (需要#include <cstdio>) cin.clear()

cin.clear()可以清除输入错误后的相应流状态,而ignore和fflush都是起到刷新输入缓冲区的作用(输入的字母留在了缓冲区,cin不能读取,如果不刷新,之后cin还是首先读到字母,导致死循环),从而是cin可以重新接收新的数据。

fflush刷新缓冲区相信大家都不陌生了,这里就不多说了,那么ignore()方法是怎样操作的呢?

以下参考C++ Reference:

ignore()方法原型是:

istream& ignore ( streamsize n = 1, int delim = EOF );功能:它从输入序列提取字符并且丢弃它们,ignore方法直到丢弃的字符数达到 n 或者丢弃的字符是 delim 时(注意,delim 也会一起被丢弃),终止函数。

参数:

n 丢弃的最大字符数, 它是 streamsize.整数类型

delim 界限符

返回值:

函数返回 *this



流状态有三种:

1) stream:: badbit

系统级的故障,如无法恢复的读写错误,流通常无法继续使用。

2) stream::failbit

可恢复的流错误,如在希望获得数值型的数据时输入了字符,

3) stream::eofbit

文件结束,同时还会设置failbit标志

流有三个函数来测试以上各个流状态:即bad(), fail()和eof(),另外流状态是否正常可以用good()来测试;流的状态字可以由rdstate()读出;另外还有两个操作用于改变流的状态:clear()和setstate(),但它们的操作结果不怎么符合我们的直觉。(注:C++ Reference中的解释是:Sets a new value for the error control state.)

setstate必须有个一个表示流状态的参数,操作结果将使指定的状态位置位(set),其他的状态位不变,无法作reset操作。clear用于设置流的状态为参数指定的状态字,它实际上是个set操作,而不是reset,它的参数有一个默认的值为goodbit,这实际是个0,等价于clear(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里面的一个例子)

#include <stdexcept>

#include <iostream>

#include <cstdio>

using namespace std;



int main()

{

int ival;

while(cin>>ival, !cin.eof())

{

if(cin.bad())

throw runtime_error("IO stream corrupted");

if(cin.fail())

{

cout << "rdstate()函数的返回值: " << cin.rdstate() << endl;

cout << "三个标记位返回的返回值: " << cin.fail() << cin.bad() << cin.eof() << endl;

cout << "goodbit标记位的返回值: " << cin.good() << endl;



//cin.clear(istream::failbit); // 这样不行

//cin.clear(istream::failbit ^ cin.rdstate()); // 可以

//cin.ignore();

cin.clear();

fflush(stdin);

cerr <<"bad data, try again:"<<endl;

//system("PAUSE");

continue;

}

cout <<ival <<endl;

}

system("PAUSE");

return 0;

}

上面的例子修正了C++ Primer书上的例子

用了2种方法清除输入错误:

cin.clear();

fflush(stdin);



cin.ignore();

cin.clear();

其中,cin.clear()可以替换为:cin.clear(istream::failbit ^ cin.rdstate());

也许大家对cin.rdstate()不太熟悉,简要说明一下:

它的原型是:iostate rdstate ( ) const;它的功能是返回流的当前内部错误标志,他的返回值是eofbit、failbit、badbit和goodbit的任意组合。


如果有任何错误,请指正!

xjy1204 2008-06-30
  • 打赏
  • 举报
回复
我们谈谈cin.clear的作用,第一次看到这东西,很多人以为就是清空cin里面的数据流,而实际上却与此相差很远,首先我们看看以下代码:

#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_base::failbit)
{
cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
}
system("pause");
}


我们定义要输入到的变量是整型,但如果我们输入了英文字母或者汉字,那就会发生错误,cin里有个方法能检测这个错误,就是cin.rdstate(); 当cin.rdstate()返回0(即ios::goodbit)时表示无错误,可以继续输入或者操作,若返回4则发生非致命错误即ios::failbit,则不能继续输入或操作.而cin.clear则可以控制我们此时cin里对这个问题的一个标识.语发如下: cin.clear(标识符); 标识符号为:

goodbit 无错误
Eofbit 已到达文件尾
failbit 非致命的输入/输出错误,可挽回
badbit 致命的输入/输出错误,无法挽回 若在输入输出类里.需要加ios::标识符号
通过cin.clear,我们能确认它的内部标识符,如果输入错误则能重新输入.结合真正的清空数据流方法cin.sync(),请看下例:

#include <iostream> 
using namespace std;
int main()
{
int a;
while(1)
{
cin>>a;
if(!cin) //条件可改写为cin.fail()
{
cout<<"输入有错!请重新输入"<<endl;
cin.clear();
cin.sync(); //清空流
}
else
{
cout<<a;
break;
}
}
system("pause");
}


上面的cin.clear()默认参数为0,即无错误,正常操作.当我们输入英文字母'k'时,它的状态标识改为fail,即错误,用cout对用户输出信息,再用cin.clear让错误标识改回为0,让我们可以继续输入,再清空流数据继续输入.如果我们没有了cin.clear,则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且我们再也没办法输入,因为错误的表示关闭了cin,所以会进入死循环.

simo110 2008-06-30
  • 打赏
  • 举报
回复
open()后如果出现异常的话,会修改状态的某些位,
并且下次还会保持这个状态,所以要clear()清掉这些状态到原始的状态

65,013

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧