调用getline()来读取一行,需要使用cin.getline(数组名,读取字符数)。
这个函数的两个参数,一个为数组名,另一个类似字符串(即想要读取20个字符需要填写21,因为最后一位要留空字符)。
上代码:
#include<iostream> int main() { using namespace std; const int a = 20; //注意,如果这里输入int a=20; 的话,编译器会提示a不是常量,因此要用const来限制 char name[a]; //字符串a存储名字 char food[a]; //字符串b存储食物名 cout << "请输入你的名字:"; cin.getline(name, a); //将用户输入的一整行内容,存储在字符串name中,长度为20。注意,这行类似cin>>,用户输入结束会自动换行。但cin读取到空格为止,cin.getline()可以读取一整行 cout << "请输入你喜欢吃的食物:"; cin.getline(food, a); //将用户输入的一整行内容,存储在字符串food中,长度为20 cout << "好了,现在我们知道:" << name << " 喜欢吃 " << food << endl; system("pause"); return 0; }
输出结果:
请输入你的名字:王 冬 请输入你喜欢吃的食物:火 龙 果 好了,现在我们知道:王 冬 喜欢吃 火 龙 果
我们发现,使用cin.getline()的确可以读取一整行,并且显示输出结果的时候,不会帮我们换行。
而cin.get()函数与cin.getline()函数基本类似,只是有一点小小的区别。
假如我们输入内容为:abc(回车),使用cin.getline()的时候会读取abc,然后把(回车)丢掉,这样当我们下次输入def(回车)的时候,将读取def,然后再丢掉(回车)。
假如我们使用cin.get(),当输入abc(回车)的时候,先读取abc,但是并没有把(回车)丢掉,下一次输入cin.get()的时候,会首先读取回车,然后因为发现回车了,认为是最后一个字符,所以停止读取后面的内容,比如说def
————准确说,是带参数的cin.get()会这样。
例如将上面那段代码的cin.getline();的两行进行修改如下:
cout << "请输入你的名字:"; cin.get(name, a); cout << "请输入你喜欢吃的食物:"; cin.get(food, a); cout << "好了,现在我们知道:" << name << " 喜欢吃 " << food << endl;
输出结果为:
请输入你的名字:wang dong 请输入你喜欢吃的食物:好了,现在我们知道:wang dong 喜欢吃
我们发现,自动跳过输入食物名,并且显示出来的也没有食物名(因为没有读取到)。
假如在两个带参数的cin.get()之间,加入一个不带参数的cin.get(),这个不带参数的cin.get()便可以处理掉那个未被读取的换行符。从而避免出现问题。
例如将上面的代码修改如下:
cout << "请输入你的名字:"; cin.get(name, a); cin.get(); //无参数的用于读取换行符 cout << "请输入你喜欢吃的食物:"; cin.get(food, a);
便可运行正常。
也可以修改为:
cout << "请输入你的名字:"; cin.get(name, a).get(); //在第一个cin.get()后面,加上.get()用于读取换行符 cout << "请输入你喜欢吃的食物:"; cin.get(food, a);
两个效果是一样的。和上面cin.getline()效果也相同。
注意,也可以这样输入:
cin.getline(name, a).getline(food, a); //连续读取两行输入的文字,并且分别储存于两个字符串之中
解释:
①cin.get()无参数的作用。有参数的cin.get()用来读取一行字符串,而无参数的cin.get()是读取一个字符——在上文,即读取了换行字符。
②为什么使用cin.get()而不是更方便的cin.getline(),是因为《一》某些老式的实现(实现是什么玩意?编译器?)不能使用cin.getline()。《二》cin.get()使得输入更为仔细——原因在于,当我们用cin.getline()的时候,字符串是有长度的,有一种可能的情况是,假如字符串是10个字符长度,用户输入了15个字符,那么就可能只读取了10个字符,后面5个就被扔掉了。而cin.get()可以通过检测下一个字符是否是换行符,来知晓停止读取的原因是不是因为,已经读取了整行。——但是怎么知晓?
③总之,get.line()使用起来简单点,而get()检查错误容易点,还能兼容老版本的实现(编译器?)
④getline()或者get()读取到的是空行的情况下:cin.getline()在需要显示字符串的位置无显示;有参数的cin.get()将跳过后续可能需要用户输入字符串,直接显示结果——即使在用户输入空行的那行代码后面输入了.get()。如代码:
#include<iostream> int main() { using namespace std; const int a = 20; //注意,如果这里输入int a=20; 的话,编译器会提示a不是常量,因此要用const来限制 char name[a]; //字符串a存储名字 char food[a]; //字符串b存储食物名 cout << "请输入你的名字:"; cin.get(name, a).get(); cout << "请输入你喜欢吃的食物:"; cin.get(food, a); cout << "好了,现在我们知道:" << name << " 喜欢吃 " << food << endl; system("pause"); return 0; }
输出结果:(在输入名字的时候直接按回车)
请输入你的名字: 请输入你喜欢吃的食物:好了,现在我们知道: 喜欢吃
但按照说明,在这种情况下,可以用cin.clear();来恢复输入,但我并没有成功。如代码:
cout << "请输入你的名字:"; cin.get(name, a); cin.clear(); //预计输入空行后面加这行代码按照说明应该能解决问题,但实际不行? <span style="white-space:pre"> </span>cin.ignore(); //实际测试,加上这行后,回复正常 cout << "请输入你喜欢吃的食物:"; <span style="white-space:pre"> </span>cin.get(food, a);
实测加上cin.ignore();后成功了。
其他存在的问题:
假如用户输入的字符串超出字符串预设的长度(即比分配的长),那么多出来的部分将被下一个字符串所读取(在使用cin.get()的情况下),或者被舍弃,但下一个字符串用户需要输入的时候无法输入(在使用cin.getline()的情况下)。
例如,需要用户输入两次字符串,且第一次超出字符串限制长度,假如限制长度为4。
当使用cin.get()的时候,用户第一次输入abcdef共6个字符,自动跳过了第二次输入,第一次输出abcd,第二次输出ef
当使用cin.getline()的时候,用户第一次输入abcdef共6个字符,自动跳过了第二次输入,第一次输出abcd,第二次输出空白。
二者的共同点都是第二次输入被关闭,只不过get()第二次输出了第一次剩余的字符,getline()的第二次输出没有输出第一次剩余字符。
字符串和数字混合输入:
当程序中,需要先输入数字再输入字符串时,可能产生输入数字后,自动跳过输入字符串的步骤。如代码:
#include <iostream> int main() { using namespace std; int a; char abc[10]; cout << "请先输入一个数字:"; cin >> a; cout << "然后请输入字符串:"; cin.getline(abc, 10); cout << endl; cout << "现在先显示数字为:" << a << " 。然后显示字符串为: " << abc << " 。字符串显示完毕。" << endl; system("pause"); return 0; }
输出结果:
请先输入一个数字:12 然后请输入字符串: 现在先显示数字为:12 。然后显示字符串为: 。字符串显示完毕。
注意:以上在输入字符串的时候,自动跳过了输入,直接显示出了最后的结果。即用户只输入了“12”然后按了回车。
这是因为cin在读取的时候,并没有舍弃输入12后的那个换行符,于是那个换行符被cin.getline(abc,10)所读取,于是认为已经输入了,故跳过了第二次输入。
对于解决方法,可以类同之间在使用带参数的cin.get()后面加不带参数的cin.get()。在cin>>a后面加入cin.get();
如
cout << "请先输入一个数字:"; cin >> a; cin.get(); <span style="white-space:pre"> </span>cout << "然后请输入字符串:";
又或者是给cin>>a;加上括号,然后后面加上.get()也可以。
如:
cout << "请先输入一个数字:"; (cin >> a).get(); <span style="white-space:pre"> </span> cout << "然后请输入字符串:";
这两种方法是等价的。