(四十七)读取一行输入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 << "然后请输入字符串:";

这两种方法是等价的。



目录
相关文章
|
4月前
|
数据采集 机器学习/深度学习 人工智能
2026年具身智能商业化浪潮前瞻:开发者工具与软件生态的万亿级掘金图谱
在具身智能执行器和传感器等硬件成本持续下降的背景下,真正驱动其大规模商业化爆发的,并非单一的硬件产品,而是其背后的软件与生态系统。正如互联网的价值最终体现在软件应用与服务上,具身智能的商业价值正在从传统的“硬件产品销售”转向“软件与服务订阅”。RaaS等创新商业模式的兴起,正是这一趋势的直接体现。这里我们将深入剖析2026年具身智能领域,特别是围绕数据采集、训练和任务开发的软件工具与服务所蕴藏的万亿级商业机遇,为开发者与投资者描绘一幅详尽的掘金图谱。
674 0
|
4月前
|
Web App开发 缓存 监控
商品销量详情接口(item_get_sales)深度分析及 Python 实现
item_get_sales接口用于获取商品销量数据,包括历史趋势、时段分布、规格占比等,助力销售策略优化、库存管理与竞品分析。支持多平台调用,提供Python示例代码,适用于电商运营与市场分析场景。
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
468 3
|
6月前
|
机器学习/深度学习 人工智能 程序员
MiniMind:3小时训练26MB微型语言模型,开源项目助力AI初学者快速入门
在大型语言模型(LLaMA、GPT等)日益流行的今天,一个名为MiniMind的开源项目正在AI学习圈内引起广泛关注。项目让初学者能够在3小时内从零开始训练出一个仅26.88MB大小的微型语言模型。
419 1
|
关系型数据库 MySQL Linux
Qt连接Mysql出现问题(一):“Driver not loaded Driver not loaded“
第一眼看见这张图我也觉得很奇怪,显示有QMYSQL但是又说没有,这不自相矛盾吗!
3023 4
|
自然语言处理 IDE 测试技术
CodeGeeX用法
【8月更文挑战第30天】CodeGeeX用法
928 6
|
人工智能 Unix Java
[oeasy]python059变量命名有什么规则_惯用法_蛇形命名法_name_convention_snake
本文探讨了Python中变量命名的几种常见方式,包括汉语拼音变量名、蛇形命名法(snake_case)和驼峰命名法(CamelCase)。回顾上次内容,我们主要讨论了使用下划线替代空格以提高代码可读性。实际编程中,当变量名由多个单词组成时,合理的命名惯例变得尤为重要。
453 9
|
存储 XML 缓存
Unity优化——脚本优化策略1
Unity优化——脚本优化策略1
245 0
|
机器学习/深度学习 Android开发
Android permission 动态申请、授权
原文:Android permission 动态申请、授权 Android permission 新特性深度学习 本篇文章介绍android permission系统,并介绍android 6.0 permission的新特性,包括权限动态申请和授权等。
1675 0
|
传感器 物联网 智能硬件
IoT设备与手机App之间实时消息通信解决方案
PLC 工控机和管理人员 App 的联动
2002 15
IoT设备与手机App之间实时消息通信解决方案