问题描述
例如有下面段代码
int main()
{
int test; // 定义一个整型变量test
cin >> test; // 输入test
cout << endl;
cout << "test=" << test << endl; // 输出test
return 0;
}
当我输入字母'a'时,输出的test=0,说明当输入的数据类型与test类型不符时,会将test置为0
于是,我可以通过这一点设计一个程序,当我输入的数据类型不合法时,则重新输入,否则输出test,如下图:
代码实现:
int main()
{
int test = 1;
do
{
cout << "请输入数字" << endl;
cin >> test;
} while (!test);
cout << "test=" << test << endl;
return 0;
}
但是当我开始调试时,却发现了如下情况:
在第一次循环输入不合法的数据类型后,之后的每次循环都跳过了cin语句,结果就进入了死循环。
解决问题
在看了《C++ Primer》的17章第1节的内容后,我终于明白了为什么循环会跳过cin。
在此之前,需要一些准备知识:
一、cin是一个对象
cin是C++编程语言中的标准输入流对象,即istream类的对象。
所以cin的本质是一个对象,是对象就要有它的属性和方法,下图是在vs2017中查看到的cin的属性和方法
二、输入流
首先通过一个例子简单了解一下cin输入流的工作原理
int test1;
char test2;
cin>>test1;
{
if(!cin.fail())
test1 = cin.get();
}
cin>>test2;
{
if(!cin.fail())
test2 = cin.get();
}
首先从键盘输入“12E”,回车结束,流就会接收到一串字符"12E/n",/n为回车
接着它就会检查流中的数据类型是否合格,然后将第一个到最后一个合格的数字字符串转成数字,赋给当前变量
之后将流中剩下的字符交给下一个cin去处理,将字符'E'赋给了test2,到/n时则停止。
所以,在这段代码中,当我输入字符'Q'时,由于没有合适的cin去接收流中的数据,那么将一直进行循环
int main()
{
int test = 1;
do
{
cout << "请输入数字" << endl;
cin >> test;
} while (!test);
cout << "test=" << test << endl;
return 0;
}
所以正确的做法是:当我在循环末尾依然无法接收流中的数据,那么我需要将流的状态重置,并且重新从键盘输入数据。cin对象为我们提供了三个函数来完善上述代码cin.clear()
:重置流cin.get()
读取流中的数据cin.fail()
:当没有读取到预期字符,则返回true
以下是完善后的代码实现:
int main()
{
int test = 1;
while (true)
{
cout << "请输入数字" << endl;
cin >> test;
if (cin.fail())
{
cin.clear();
cin.get();
continue;
}
else
{
break;
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。