本系列文章是配合我发布的《C++编程基础》系列视频教程的补充。
在《C++编程基础》介绍循环语句结构的课里,我们在do-while结构中用cin来通过输入流将接收到的整数赋给x并判断数值的范围,简化后代码如下:
1#include
2
3int main(int argc, const char * argv[]) {
4 using std::cout;
5 using std::endl;
6 using std::cin;
7
8 int x;
9 do{
10 cout<<"Please input an integer:"<<endl;
11 cin>>x;
12 if(x>10){
13 cout<<"x is greater than 10."<<endl;
14 if(x==15){
15 cout<<"x is equal to 15."<<endl;
16 }
17 }
18 else if(x<5){
19 cout<<"x is less than 5."<<endl;
20 }else{
21 cout<<"x is between 5 and 10."<<endl;
22 }
23 }while(x!=0);
24 return 0;
25}
在运行时,如果正常输入整数类型的数据,程序能够按照我们想看到的顺序执行:
正常输入整数的输出结果:
Please input an integer:
3
x is less than 5.
Please input an integer:
34
x is greater than 10.
Please input an integer:
0
x is less than 5.
Program ended with exit code: 0
然而,在实际应用中我们无法阻止用户输入非整数类型或者溢出的数据,当输入时,程序如果不做任何判断,得到的结果会和我们的期望相去甚远,例如,当输入了3.8时输出会怎样呢?
在xcode中,我得到了这样的输出:
Please input an integer:
3.8
x is less than 5.
Please input an integer:
x is less than 5.
Program ended with exit code: 0
程序只在给了我一次输入3.8的机会,在第二次提示输入整数“Please input an integer:”时并没有停留等待用户输入,而是直接作出了判断并退出了程序。
如果输入的是aaa,得到的输出是如下结果:
Please input an integer:
aaa
x is less than 5.
Program ended with exit code: 0
程序在输入aaa后直接作出了判断并退出。
得到这些不正常的输出原因在于当cin将收到的输入传递给整数变量x时遇到了非整型数值。在输入3.8时,x收到3之后即遇到了小数点,因此先对3做了判断,得出小于5的结果,而对输入流中残留的小数点,则被认定为了无效,x值变为了0,而正好满足了跳出do-while循环的条件结束了运行,如果这里的do-while的执行条件并非设的是x!=0,则程序可能会陷入死循环的状态。
为了判断cin输入流中得到的字串是否为有效的整数类型,就需要加上如下的条件语句结构作为在do-while循环里判断x取值范围运行之前的大前提:
if(cin>>x&&cin.get()=='\n'){
//判断x取值范围
}
这个条件可以排除cin赋给x失败的情况(如输入aaa或输入值溢出了整数类型的最大限度)和cin中数字后面跟着的不是换行符“\n”的情况(如3.8中的3.)。例如在输入3.8这样的数据,程序将3赋给x后会因为3后面并不是跟着一个换行符'\n'而使条件语句里的内容不被执行,而下一次循环时由于输入流中残留着“8”,再次赋给了x,所以不等用户输入,结果就中出现了“x is between 5 and 10.”
输出结果:
Please input an integer:
3.8
Please input an integer:
x is between 5 and 10.
...
为了清除cin中的残留数据以防止干扰下次循环中的操作,这就需要将上述语句修改为:
if(cin>>x&&cin.get()=='\n'){
//判断x取值范围
}else{
...
cin.clear();
cin.ignore(INT_MAX, '\n');
}
其中,cin.clear();负责清除输入流的错误标识以便之后的输入操作正常运行。cin.ignore(INT_MAX, '\n');则用来最大程度地将输入流中的字符忽略。cin.ignore函数用来忽略输入流中的数据,它的两个参数,第一个参数用来和cin中忽略的字符数进行比较,当计数到达第一个参数的值时或者遇到第二个参数(一个字符)时才终止函数运行。
然而,这样的程序仍有可能不按预期的执行,由于我们最初要求的是x==0的时候退出循环,如果输入像“aaa”这样的字符串时,x的值为0,会立即跳出循环,而不会再给用户重新输入的机会。为此,如果还想让退出条件为x==0,则可以改变do-while的条件表达式为永远为真,即do-while(true);的模式,然后将x==0的判断放在x<5时的判断中去,值为0时使用break;语句直接跳出循环体。此番调整后,程序的流程图变化如下:
程序实现如下:
1#include
2
3int main(int argc, const char * argv[]) {
4 using std::cout;
5 using std::endl;
6 using std::cin;
7
8 int x;
9 do{
10 cout<<"Please input an integer:"<<endl;
11 if(cin>>x&&cin.get()=='\n'){
12 if(x>10){
13 cout<<"x is greater than 10."<<endl;
14 if(x==15){
15 cout<<"x is equal to 15."<<endl;
16 }
17 }
18 else if(x<5){
19 if(x==0){
20 break;
21 }else{
22 cout<<"x is less than 5."<<endl;
23 }
24 }else{
25 cout<<"x is between 5 and 10."<<endl;
26 }
27 }else{
28 cin.clear();
29 cin.ignore(INT_MAX, '\n');
30 cout<<"Please input an integer!"<<endl;
31 }
32 }while(true);
33 return 0;
34}
说了这么多,希望对大家有点儿帮助,判断输入是否为整型的方式也不止一种,就是还没找到更为简单的方式。这里实在忍不住想吐槽一下:C++做这种判断可是比Java麻烦太多啦!
欢迎点击右下方↓↓"在看"↓↓来分享![706d80c4d03ee513004604a6a0abef35.gif](https://i-blog.csdnimg.cn/blog_migrate/9cd5ba703a1a3f81606fb94dcce41f6f.gif)