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

来源:互联网 发布:大数据人物画像 编辑:程序博客网 时间:2024/05/14 02:35

调用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中,长度为20cout << "好了,现在我们知道:" << 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 << "然后请输入字符串:";

这两种方法是等价的。



0 0