C++:使用cin.getline()输入超过规定字符数
创始人
2024-03-19 17:26:07
0

cin.getline的用法:

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

比如:

#include iostream
using std::cin;
int main(){char a[20];cin.getline(a,20);...
}

如果输入缓冲区的字符少于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. 如果我们输入了19个字母a,然后按回车发送,结果如下:
    cin.fail() is false
    Input a string: aaaaaaaaaaaaaaaaaaa
    cin.fail() is false
    
    可以看到前面和后面cin.fail()的值都是false
  2. 如果我们输入了20个字母a,然后按回车发送,结果如下:
    cin.fail() is false
    Input a string: aaaaaaaaaaaaaaaaaaaa
    cin.fail() is true
    
    可以看到第二次 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;
}

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

Input a string: aaaaaaaaaaaaaaaaaaaa
m is 

我们看到第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;
}

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

m is 
m is 
m is 
m is 
m is 
m is 
m is 
m is
...

也就是说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;
}

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

Input a string: aaaaaaaaaaaaaaaaaaaa
m is a

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

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

cin.getline(a,20);
if(cin.fail()){cin.clear();while(cin.get()!='\n') continue;
}

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...