您的位置:首页 > 其它

(四十七)读取一行输入getline()和get()

2015-12-03 16:35 267 查看
调用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 << "然后请输入字符串:";

这两种方法是等价的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: