参考:
C++中的cin函数和异常的来源(failbit)与处理(clear)
运行下面代码时,发现一旦输入字符型数据时,会导致后续运行程序时直接跳过cin函数
#include <iostream>
#include <string>
using namespace std;
void main()
{
int id ;
while (1)
{
//这个程序是从键盘上读取一个整型输入并将其打印出来
cout << "This is a test! Input:" <<endl;
cin >> id;
cout << "输入完成!" << endl;
cout << "ID:" << id << endl;
system("pause");
}
}
一旦输入字符数据,后面再运行的时候都会直接跳过 cin>>id 代码,使得程序出错
原因分析:
因为cin是一个输入流,当要求赋值给一个整形时,输入的类型可能与该整型不匹配,导致缓存溢出。这时候使得cin流状态异常,在下次执行cin时直接跳过。C++中用:eofbit、badbit和failbit来标记输入流状态。
这里引用smallayy的解释:
- 每一个输入(输出)对象就代表一个输入(输出)流
- 输入(输出)对象中的流状态成员标记了输入(输出)流当前的状况,当eofbit、badbit、failbit三个标记位均为0时表示流状态正常
- 一但某个或几个标记位被设置,表示对象的流状态出现相应状况,流将对后面的输入(输出)关闭,直到标记位被清除
- 只有在流状态良好的情况下,cin函数才能被执行
cin流状态获取
获取cin流状态可通过下面几个函数获取,cin.fail(),cin,good() 用的比较多
-
cin.fail()
:该函数用于检查最近一次的输入操作是否失败。如果最近的输入操作失败(例如,当预期的数据类型与实际输入的数据类型不匹配时),则返回true
;否则返回false
。在输入失败的情况下,可以使用cin.clear()
函数来清除错误状态,并使用cin.ignore()
函数来清除输入缓冲区中的无效输入。 -
cin.bad()
:该函数用于检查输入流是否处于糟糕状态。如果输入流遇到了严重的错误(如内存错误),则返回true
;否则返回false
。bad()
函数返回true
时,通常表示输入流已经不可用,并且需要进行相应的错误处理。 -
cin.eof()
:该函数用于检查是否已达到输入流的末尾(End-Of-File)。如果已经到达输入流的末尾,则返回true
;否则返回false
。当遇到文件末尾时,通常用于循环中以判断是否终止输入操作。 -
cin.good()
:该函数用于检查输入流是否处于良好状态。如果输入流未遇到任何错误,并且未达到文件末尾,则返回true
;否则返回false
。good()
函数通常用于检查输入流是否仍然可用于读取数据。
输入流异常解决办法
需要先使用cin.clear()
函数将badbit置为0,再将输入缓冲区清空。
注:必须先置位再清空缓冲区!
int id ;
while (1)
{
//这个程序是从键盘上读取一个整型输入并将其打印出来
cout << "This is a test! Input:" <<endl;
cin >> id;
cout << "输入完成!" << endl;
cout << "ID:" << id << endl;
cin.clear();//将badbit置为0
cin.ignore(10,'\n');
//清除缓冲区知道遇到‘\n’符或者清空的字符数达到10
//如果缓冲区内数据较多,可以将这里的10换成100或者更大的数
system("pause");
}