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;
}
运行这个代码:
a
,然后按回车发送,结果如下:cin.fail() is false
Input a string: aaaaaaaaaaaaaaaaaaa
cin.fail() is false
cin.fail()
的值都是false
。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;
}