cin>>与cin.getline()混用时的问题

问题描述

很多时候我们会遇到这样一种情景,第一行读入一个整数n,第二行输入一行字符串str

大家会自然地写出如下代码:

1
2
3
4
5
6
7
int n;
char str[80], str2[80];
cout<<"Input an integer:";
cin>>n;
cout<<"Input a string:";
cin.getline(str, 80);
cout<<"End of Input!";

但是当运行在控制台的时候,我们先输入一个整数,然后回车,然后试图输入一行字符串,会发现第二行字符串没有被输入。当我们检查到底输入了什么的时候,发现str为空字符串。

控制台显示内容如下:

1
2
Input an integer:5
Input a string:End of Input!

原因

cin>>的工作方式为,根据>>后面的数据类型读取数据,从非空白字符开始,遇到回车'\n'、空格' '、制表符'\t'等时结束。结束时将这些空白字符保留在输入流中。

cin.getline()的工作方式为,从输入流读取一行数据,遇到'\n'结束。结束时不在输入流中保留'\n'

在上面的代码和输入中,我们输入5之后按了一下回车,通过判断回车判断对n输入结束。这种情况下,cin不会删除输入流中的'\n',换行符将被留在输入流里面。接下来就被cin.getline()读入,其判断输入为换行符,结束本行输入,因而str为空。

解决方法

cin>>cin.getline()之间把这个换行符从输入流清除即可。

可以使用cin.ignore();忽略这个换行符,也可以使用cin.get();将这个换行符读入。

于是修改后的代码为:

1
2
3
4
5
6
7
8
9
int n;
char str[80], str2[80];
cout<<"Input an integer:";
cin>>n;
cin.ignore();
// 或者 cin.get();
cout<<"Input a string:";
cin.getline(str, 80);
cout<<"End of Input!";

扩展

cin.get()也能输入一行字符串,这种场景的调用方式和cin.getline()一模一样,只是把getline改成了get,如:

1
cin.get(str,80);

那么它和cin.getline()有什么区别呢?

cin.get在这种用法下将输入本行时最后的换行符保留在了输入流中,而cin.getline()不保留换行符。