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

简介:

调用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 << "然后请输入字符串:";

这两种方法是等价的。



目录
相关文章
|
6月前
|
存储 C语言
C 语言文件读取全指南:打开、读取、逐行输出
要从文件读取,可以使用 r 模式: FILE *fptr; // 以读取模式打开文件 fptr = fopen("filename.txt", "r"); 这将使 filename.txt 打开以进行读取。 在 C 中读取文件需要一点工作。坚持住!我们将一步一步地指导您。 接下来,我们需要创建一个足够大的字符串来存储文件的内容。 例如,让我们创建一个可以存储多达 100 个字符的字符串:
612 2
C 语言文件读取全指南:打开、读取、逐行输出
|
3月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
43 0
|
5月前
|
C语言
C语言进阶——文件的读写(文件使用方式、文件的顺序读写、常用函数、fprintf、fscanf)
C语言进阶——文件的读写(文件使用方式、文件的顺序读写、常用函数、fprintf、fscanf)
41 0
|
Shell Linux Perl
Shell基础学习---3、Read读取控制台输入、函数、正则表达式入门
Shell基础学习---3、Read读取控制台输入、函数、正则表达式入门
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 读取配置文件 | 函数接口形参 | 读取配置文件的逐行遍历操作 | 读取一行文本 | 查找字符 | 删除字符串前后空格 )
【C 语言】文件操作 ( 配置文件读写 | 读取配置文件 | 函数接口形参 | 读取配置文件的逐行遍历操作 | 读取一行文本 | 查找字符 | 删除字符串前后空格 )
171 0
|
缓存 数据安全/隐私保护 程序员
getchar函数输入与缓冲区
getchar函数输入与缓冲区
147 0
getline读取一行的数据
getline读取一行的数据
66 0
编写一个程序,如果名为Exercise12_15.txt的文件不存在,则创建该文件。使用文本I/O将随机产生的100个整数写入文件,文件中的整数由空格分开。从文件中读回数据并以升序显示数据。
编写一个程序,如果名为Exercise12_15.txt的文件不存在,则创建该文件。使用文本I/O将随机产生的100个整数写入文件,文件中的整数由空格分开。从文件中读回数据并以升序显示数据。
287 0
fwrite()读取长度错误
fwrite()读取长度错误
110 0
|
缓存 移动开发 编译器
C++STL开发温习与总结(六): 6.C++语言输入/输出流定义之输入/输出格式控制
C++STL开发温习与总结(六): 6.C++语言输入/输出流定义之输入/输出格式控制
C++STL开发温习与总结(六): 6.C++语言输入/输出流定义之输入/输出格式控制