• C++:使用cin.getline()输入超过规定字符数


    cin.getline的用法:

    cin.getline(char *arr, int SIZE);
    
    • 1

    比如:

    #include iostream
    using std::cin;
    int main(){
    	char a[20];
    	cin.getline(a,20);
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果输入缓冲区的字符少于20个,getline会把这些字符全部读入a中,然后将结尾的换行符'\n'处理掉,并在字符串a的结尾的添加\0

    也就是说,如果第二个参数为SIZE,那么getline最多能够读入SIZE-1个有效字符。

    我们来考虑极端情况,还是上面的例子,如果输入19个字母然后按回车发送,此时缓冲区里的符号有19个字母然后加一个换行符'\n'。这种情况cin.getline(a,20)能够正确的处理(在大小为20个数组的前19个位置装入输入的这19个字母,然后在末尾添加'\0',同时处理掉缓冲区里的'\n'

    但是,如果输入了20个字母,此时缓冲区里面的符号有20个字母加一个换行符'\n'。这种情况cin.getline(a,20)就不能正确处理了,当getline()读到第20个字符,发现它仍然不是换行符'\n',它就不会再读这第20个字符,直接把从那之后的字符都留在缓冲区里(当然输入最后的换行符也留在了缓冲区)。只把前19个字符装入字符串a,然后在字符串的末尾添加'\0'。而且还会设置失效标志fail()true,并且关闭后面的输入。

    这是什么意思呢?请看下面的解释:

    首先来解释什么是设置fail()true

    #include 
    
    int main() {
    
        using namespace std;
        char a[20];
        cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        cout << "Input a string: ";
        cin.getline(a,20);
        cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行这个代码:

    1. 如果我们输入了19个字母a,然后按回车发送,结果如下:
      cin.fail() is false
      Input a string: aaaaaaaaaaaaaaaaaaa
      cin.fail() is false
      
      • 1
      • 2
      • 3
      可以看到前面和后面cin.fail()的值都是false
    2. 如果我们输入了20个字母a,然后按回车发送,结果如下:
      cin.fail() is false
      Input a string: aaaaaaaaaaaaaaaaaaaa
      cin.fail() is true
      
      • 1
      • 2
      • 3
      可以看到第二次 cin.fail()的值变成了 true

    这就解释了什么是设置fail()true,然后再来解释什么是关闭后面的输入:

    再看下面这个代码:

    #include 
    
    int main() {
    
        using namespace std;
        char a[20];
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        cout << "Input a string: ";
        cin.getline(a,20);
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        if(cin.fail()){
            char m = cin.get();
            cout << "m is " << m << endl;
        }
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行这个代码,输入20个字母a,然后按回车发送,结果如下:

    Input a string: aaaaaaaaaaaaaaaaaaaa
    m is 
    
    • 1
    • 2

    我们看到第20个字母a并没有读入变量m中,这是由于输入被关闭了的原因。

    如果这时我们将代码改得危险一点:

    #include 
    
    int main() {
    
        using namespace std;
        char a[20];
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        cout << "Input a string: ";
        cin.getline(a,20);
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        while(cin.fail()){
            char m = cin.get();
            cout << "m is " << m << endl;
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行它,就会发现程序进入了死循环

    m is 
    m is 
    m is 
    m is 
    m is 
    m is 
    m is 
    m is
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    也就是说cin.get()一直没有成功,cin.fail()也一直是true

    解决方法是使用cin.clear(),clear()会重置失效位,并打开输入.

    将代码修改如下:

    #include 
    
    int main() {
    
        using namespace std;
        char a[20];
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        cout << "Input a string: ";
        cin.getline(a,20);
        //cout << "cin.fail() is " << boolalpha << cin.fail() << endl;
        while(cin.fail()){
            cin.clear();
            char m = cin.get();
            cout << "m is " << m << endl;
        }
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行这个代码,同样输入20个字母a,按回车发送,结果如下:

    Input a string: aaaaaaaaaaaaaaaaaaaa
    m is a
    
    • 1
    • 2

    我们发现第20个字母a成功读入了m中,且循环顺利退出,程序结束。也就是cin.get()成功了,cin.fail()也被重置为了false

    所以,在使用getline()函数时,最好在后面加上如下的语句,以防止可能出现的输入过大的问题:

    cin.getline(a,20);
    if(cin.fail()){
    	cin.clear();
    	while(cin.get()!='\n') continue;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    C Primer Plus(6) 中文版 第10章 数组和指针 10.8 变长数组(VLA)
    看完阿里最新产500页微服务架构笔记,感觉我格局太小
    Windows ssh免密访问Linux服务器
    js执行机制
    03 基础配置webpack3打包vue文件
    containerd命令操作
    【P60】JMeter Jtl 文件的 html 格式输出
    hand_mysql
    【SpringBoot】怎么在一个大的SpringBoot项目中创建多个小的SpringBoot项目,从而形成子父依赖
    宏观经济学通识课-读书笔记
  • 原文地址:https://blog.csdn.net/weixin_40064300/article/details/128191604