mylogo

退役程序员的茶室 RetiredCoder.cn

← 返回上一页

C++编程技巧: 如何判断输入是否为整型

2025-04-21 12:59:47

本系列文章是配合我发布的《C++编程基础》系列视频教程的补充。这篇文章我们来讲讲如何判断输入是否为整型。

在《C++编程基础》介绍循环语句结构的课里,我们在do-while结构中用cin来通过输入流将接收到的整数赋给x并判断数值的范围,简化后代码如下:

#include <iostream> 
int main(int argc, const char * argv[]) {
    using std::cout;
    using std::endl; 
    using std::cin;
    int x; 
    do{
        cout<<"Please input an integer:"<<endl;
        cin>>x;
        if(x>10){
            cout<<"x is greater than 10."<<endl;
            if(x==15){
                cout<<"x is equal to 15."<<endl;
            }
        }elseif(x<5){
            cout<<"x is less than 5."<<endl;
        }else{
            cout<<"x is between 5 and 10."<<endl;
        }
    }while(x!=0);
    return0;
}

在运行时,如果正常输入整数类型的数据,程序能够按照我们想看到的顺序执行:

Image

正常输入整数的输出结果:

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中数字后面跟着的不是换行符“”的情况(如3.8中的3.)。例如在输入3.8这样的数据,程序将3赋给x后会因为3后面并不是跟着一个换行符’’而使条件语句里的内容不被执行,而下一次循环时由于输入流中残留着“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;语句直接跳出循环体。此番调整后,程序的流程图变化如下:

Image

程序实现如下:

#include <iostream> 
int main(int argc, const char * argv[]) {
    using std::cout;
    using std::endl;
    using std::cin;
    int x;
    do{
        cout<<"Please input an integer:"<<endl;
        if(cin>>x&&cin.get()=='\n'){
            if(x>10){
                cout<<"x is greater than 10."<<endl;
                if(x==15){
                    cout<<"x is equal to 15."<<endl;
                }
            }elseif(x<5){
                if(x==0){
                    break;
                }else{
                    cout<<"x is less than 5."<<endl;
                }
            }else{
                cout<<"x is between 5 and 10."<<endl;
            }
        }else{
            cin.clear();
            cin.ignore(INT_MAX, '\n');
            cout<<"Please input an integer!"<<endl;
        }
    }while(true);
    return0;
}

说了这么多,希望对大家有点儿帮助,判断输入是否为整型的方式也不止一种,就是还没找到更为简单的方式。这里实在忍不住想吐槽一下:C++做这种判断可是比Java麻烦太多啦!