有问题的代码 这是一个判断并要求用户必须输入无符号整数的程序,巧妙使用 cin.fail标志位,它在CIN输入类型与接收变量类型不一致时被设置为1 ,大幅简化了判断程序
#include <iostream>
using namespace std;
int main()
{
unsigned long num = 0;
cout << "请输入一个数字:" << endl;
cin >> num;
while ( cin.fail() ){
cout << "num必须输入数字,请重新输入:" << endl;
cin >> num ;
}
return 0;
}
上面的代码 如果输入的不是数字 就会陷入死循环 是因为 cin.fail 标志位始终是1 没有被复位。然后看网上一段代码 照猫画虎修改后:
#include <iostream>
using namespace std;
int main()
{
unsigned long num = 0;
string num_input_string; // 增加一个字符串变量
cout << "请输入一个数字:" << endl;
cin >> num;
while ( cin.fail() ){
cin.clear();
cin >> num_input_string; // 增加这行代码 原来的目的是把错误输入值保存到num_input_string;
cout << num_input_string << 不是数字,请重新输入:" << endl;
cin >> num ;
}
return 0;
}
上面代码居然解决了问题,可是我想了半天还是没有明白,增加了 cin.clear(); 请清空了cin的缓冲可以理解,不能理解的是为什么只要删除了 cin >> num_input_string; 输入字母程序就又陷入了死循环,在网上查了几篇贴文也没说明白的。
后来查询了 cin.clear(); 才明白 ,cin.clear();并不是清空CIN缓冲数据,而是让输入流重新处于有效状态,而cin.sync(); 才是真正的清空CIN的缓冲数据,这2个必须一起顺序使用才起作用。那么为什么上面的代码加了 cin >> num_input_string; 也可以? 是因为 cin >> num_input_string; 在cin.clear();之后是转存了 上一个输入的缓冲数据,而这个数据肯定是字符型的 所以 cin.fail 标志位被设置成了0 ;导致代码 不会死循环,这不是真确方法,完全是歪打正着。
最后正确的代码应该是: 只要增加cin.clear(); cin.sync(); 清空cin 就不会陷入死循环了。
#include <iostream>
using namespace std;
int main()
{
unsigned long num = 0;
cout << "请输入数字:" << endl;
cin >> num;
while ( cin.fail() ){
cin.clear();
cin.sync();
cout << "必须输入数字,请重新输入:" << endl;
cin >> num;
}
return 0;
}