#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,所以会进入死循环.
参考原文:http://www.cnblogs.com/tonglingliangyong/p/3908463.html
关于sync()函数的作用应该是同步缓冲区的数据,而并非清除缓冲区的数据(下面补充)。清除缓冲区数据用下面这种方式。
cin.ignore(numeric_limits<std::streamsize>::max(),'/n');//清除当前行
cin.ignore(numeric_limits<std::streamsize>::max()); //清除cin里所有内容
numeric_limits<std::streamsize>::max()是climits头文件定义的流使用的最大值,你也可以用一个足够大的整数代替它。
关于sync()的例子:
#include <iostream>
#include <fstream> void file_abc()
{
std::ofstream f("test.txt");
f << "abc\n";
} void file_123()
{
std::ofstream f("test.txt");
f << "123\n";
} int main()
{
file_abc(); // file now contains "abc"
std::ifstream f("test.txt");
std::cout << "Reading from the file\n";
char c;
f >> c;
std::cout << c;
file_123(); // file now contains "123"
f >> c;
std::cout << c;
f >> c;
std::cout << c << '\n';
f.close(); file_abc(); // file now contains "abc"
f.open("test.txt");
std::cout << "Reading from the file, with sync()\n";
f >> c;
std::cout << c;
file_123(); // file now contains "123"
//f.sync();
f >> c;
std::cout << c;
f >> c;
std::cout << c << '\n';
}
知乎见解:
为了更好理解,以 std::ifstream f("test.txt"); 为例,对象 f 和磁盘上的文件 test.txt 就是两个相关联但不同的东西。f 有自己的缓冲区用来缓冲从 test.txt 读取的内容。而 sync() 则是强制将 test.txt 的内容「同步」到缓冲区。
比如 test.txt 内容本来是 abc。f 被创建后缓冲区内可能就直接加载了这三个字符,今后的读写就都直接从缓冲区,而非文件本身做了。这样一来,如果此时 test.txt 的内容立即被另一个程序改成了 123,从 f 对象里读取的内容仍旧是 abc。但如果调用 sync(),则缓冲区会同步成 123。
作者:邱昊宇
链接:https://www.zhihu.com/question/40160488/answer/85242357
来源:知乎
输出(编译器g++):
续: