C++排雷:17. 输入整行字符串的getline(空行输出、回车吸收)问题

需求:

  • 输入字符
  • 可选择整行输入和逐字输入两种模式
    问题代码:
#include<iostream>
#include<string>

using namespace std;
int main()

{
	int choice;
	cout << "整行输入请输入1,逐字输入请输入0\n";
	cin >> choice;
	
	if (choice==1)
	{
		string content_str;
		cout << "现在是整行输入模式\n"<<"请整行输入你要输入的内容\n";
		while (getline(cin, content_str))
		{
				cout << content_str << endl;
			//if (content_str.empty())
			//{
			//	break;
			//}
		}
	}
	
	else if(choice==0)
	{
		cout << "现在是逐字输入模式\n" << "请逐字输入你要输入的内容\n";
		char content_str;
		while (cin>>content_str )
		{
			cout << content_str<<endl;
		}
	}
	
	else
	{
		cout << "输入有误\n";
	}

	return 0;
}

我们choice输入1进入整行输入模式,运行结果如下:
在这里插入图片描述
很奇怪,还没有cin,就已经进入了结构体,运行了cout语句了。看来先进入循环后,执行一次再进行条件判断吧?

为了检测,这里把string content_str;

  • 修改为string content_str(“初始值”);
    再运行:
    在这里插入图片描述
    这一结果推翻了之前的推测,现在情况有些难以判断,所以设置断点进行debug:
    在这里插入图片描述进入while之前,初始值正确设置,讲道理,如果不先经过条件判断,直接运行语句的话,直接输出的应该是“初始值”而非空行。
    这里继续下一句,奇怪的事情发生了:
    在这里插入图片描述可以看到,本次并没有提示控制台输入,而是直接进入了结构体,一进去content_str的值就被清空了!
  • 个人认为这个错误是很严重的,如果我想以空行为条件判断,那么在程序一运行时,就直接进入了空行条件结构体了。

很奇怪啊,结构体是在content_str的作用域内的,为什么一进去就清空了呢?我怀疑是getline的作用,使cin直接接受了回车,将回车推到了content_str内,所以输出了空行。

那么回车是从哪里来的呢?分析整个流程:

  • 在确定输入模式的时候,我在控制台敲了1+回车
  • 在conten_str的定义下,输出的“ cout << “现在是整行输入模式\n”<<“请整行输入你要输入的内容\n”; ”当中有两个换行符

先考虑第一个情况,这里把模式1的代码块拿出来单独运行:
在这里插入图片描述果然!空行消失了
问题找到了,那,到底是什么原因,使前面cin输入的1+回车影响到了content_str呢?

原来键盘是输入到缓冲区的,cin 和cin.getline()实际上是从缓冲区读入数据,当缓冲区有内容时,会直接从缓冲区读取,不会要求键盘输入。

  • cin只是在缓存区中,把字符读走,会剩余/n在缓存区中
  • 但是getline对/n极度敏感,导致getline刚开始读入便遇到/n于是停止读入数据。

因此,要在cin与getline之间加入

  • cin.get();
  • 或cin.ignore();
    这样,程序就可以正常运行了,吸收了换行符后,可以加入循环退出语句:
			if (content_str.empty())
			{
				break;
			}

其中cin.get()用来舍弃输入流中不需要的字符 或者舍弃回车。
cin.ignore( a, ch )表示从 cin 中提取并忽略字符。而每抛弃一个字符,它都要进行计数和比较字符:如果计数值达到 a 或者被抛弃的字符是 ch ,则cin.ignore() 函数执行终止;否则,它继续等待。

  • cin.ignore(1024, ‘\n’),通常把第一个参数设置得足够大,这样实际上是为了只有第二个参数 ‘\n’
    起作用,所以这一句就是把回车(包括回车)之前的所以字符从输入缓冲流中清除出去。
  • 如果默认不给参数的话,默认参数为cin.ignore(1, EOF),即把EOF前的1个字符清掉,没有遇到EOF就清掉一个字符然后结束

热门文章

暂无图片
编程学习 ·

蓝鲸平台mongodb集群异常处理

问题回顾 蓝鲸平台中的配置平台(cmdb)数据存放在了mongodb集群中(三台mongodb服务器组成的集群),偶然间发现集群中的一个节点日志有报错。 报错信息如下: 2020-06-30T19:27:50.622+0800 I REPL [replication-0] We are too stale to use 10.10.10.2:27017 as a sync …
暂无图片
编程学习 ·

用Python读取pg数据库,准确统计每一张表的数据量,输出中英文表名和数据量

1 前言 在我们工作中,有时候老板关系我们手上到底有多少数据,每一张表中到底有多少数据量,整个库又有多少数据量?要给他一个准确的数据,给出一张详细清单。 在网上遇到的一种做法是使用navicat写SQL语句统计pg_class里面的reltuples这个列数据,但是发现这个数据有很大偏…
暂无图片
编程学习 ·

提高复杂网络分析效率!中国科学家研发强化学习新框架

提高复杂网络分析效率!中国科学家研发强化学习新框架近日,中国国防科技大学、美国加州大学洛杉矶分校和哈佛医学院的研究人员研发了一个深度强化学习框架FINDER。相比于现有的解决方案,FINDER能够更快速、更高效地找到复杂网络中一组最关键的节点,进而使复杂网络以较高的效…
暂无图片
编程学习 ·

云服务器与物理服务器哪一种更适合企业应用部署?

云服务器与物理服务器哪一种更适合企业应用部署呢? 全球企业早已意识到利用高端技术来提高工作效率并获得竞争优势。从目前的舆论方向来看,部分企业的转型主要围绕着如何将旧系统和应用迁移到“云”。而选用“云”的原因,是因为它的可伸缩性,高效率和高可用性。然而,有些人…
暂无图片
编程学习 ·

STM32G031K LL库的使用 - IIC

说明:驱动基于STm32G031K6,其他型号需自行做改动。注:因为之前项目暂未用到LL库的IIC,所以此驱动未经过实机验证。欢迎反馈使用中的问题。IIC的初始化: CubeMX生成void STM32LLI2C1_Init(void) {LL_I2C_InitTypeDef I2C_InitStruct = {0};LL_GPIO_InitTypeDef GPIO_InitSt…
暂无图片
编程学习 ·

Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

注入实现方式@Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byType的,如果存在多个同一类型的bean,则使用@Qualifier来指定注入哪个beanName的bean。与JDK的@Resource的区别:@Resourc…
暂无图片
编程学习 ·

贪心:P2240 【深基12.例1】部分背包问题(洛谷)

贪心算法的讲解: 贪心算法 本题链接 第一种:结构体解题 #include<bits/stdc++.h> using namespace std; struct node {double w;//重量double v;//价值double p;//均价 }a[101]; int N; double T,sum; bool cmp(node a, node b) {return a.p > b.p; } int main() {…
暂无图片
编程学习 ·

亚马逊ERP系统独立部署OEM定制无限开账号

马逊无货源模式,和传统无货源模式操作一样!需要咱们开店利用软件去采集商品,上传到咱们店铺,有订单了去上家拍下,发到深圳的中转仓,进行商品检测二次包装,发往国外!赚取汇率差! 要做亚马逊无货源模式,那么亚马逊ERP也是必须用的!市场erp已经出现很多,但是真正做技术…
暂无图片
编程学习 ·

Android客户端调起地图定位不准,导航路线出现偏差,目的地坐标偏离

前言 APP调起地图导航出现偏差 是什么问题造成的呢 一:可能是模糊定位造成的 二:也有可能 改变了经纬度的数据 解决思路如下 先了解一下调起高德APP的各个参数是什么 百度地图 参数如下:参数名称 描述 是否必选 格式(示例)origin 起点名称或经纬度,或者可同时提供名称和经纬…
暂无图片
编程学习 ·

组合数学4-全排列与算法

文章目录全排列与算法一 钟声里的全排列**思考**:生成算法二 字典序法1.递归2.字典序法例1:生成字母abc的全排列例2:生成123的全排列例3:生成839647521的全排列3.**思考**:局部连续变化三 SJT算法(Steinhaus–Johnson–Trotter algorithm)1. 引出思路2. 可移动数(mobil…
暂无图片
编程学习 ·

opencv画3d骨架图

效果: import matplotlib.pyplot as plt import numpy as np# h36m骨架连接顺序,每个骨架三个维度,分别为:起始关节,终止关节,左右关节标识(1 left 0 right),用来区别颜色 human36m_connectivity_dict = [[0, 1, 0], [1, 2, 0], [2, 6, 0], [5, 4, 1], [4, 3, 1], [3, 6…
暂无图片
编程学习 ·

JAVA笔记[2]20200701

JAVA笔记【2】对象与类继承 对象与类LocalDate类;static LocalTime now() 构造一个表示当前日期的对象 static LocalTime of(int year,int month,int day) 构造一个表示给定日期的对象 int getYear() int getMonthValue() int getDayOfMonth() 得到当前日期的年、月和日 DayOf…
暂无图片
编程学习 ·

web编程期末大作业

web编程期末大作业—项目一实验内容: 首先在项目文件的终端中输入 npm install xxx 安装所有依赖的node modules 其次建立2个mysql表,保存用户信息和操作日志。 然后我们需要建立连接mysql配置文件要求1:用户注册可登录网站,非注册用户不可登录。 登录页然后是登录页路由,…
暂无图片
编程学习 ·

node.js实现爬虫项目展示大作业

一、项目要求二、实现 1、用户可注册登录网站,非注册用户不可登录查看数据 登录页、注册页 <!DOCTYPE html> <html ng-app="login"> <head><meta charset="utf-8" /><title>Login</title><link rel="stylesh…
暂无图片
编程学习 ·

HTML 基本框架及一些基础命令

最近在学习HTML,是在菜鸟教程进行学习的,下面只是对自己所学习的只是进行总结,并对一些基础命令进行记录,便于自己后面使用的查找。1.一个基本的HTML框架就是这样的。HTML也是文本语言,可以用txt,notepad++文本编辑器进行编辑,当然还是更推荐使用专门的HTML编辑器来编辑…
暂无图片
编程学习 ·

转:好领导要具备的十个条件

个人理解:信守承诺,敢做敢当,言行一致 信守承诺,敢做敢当,言行一致,绝不虚伪处世 帮助员工成长,与大家一起成就;团队不是领导一个人的领地,而是大家共同成长与奋斗、一起收获的地方 目的和行动一致,一以贯之,坚持不懈,有张有驰;成功是有惯性的 严于律己,常于过程…
暂无图片
编程学习 ·

区间问题合集【Python】

这篇文章记录了区间调度问题之重叠区间、区间合并以及求区间交集。 解决区间问题的一般思路是先排序,再操作。关于排序方式的选择,不同的题型选择不同的排序方式:对于重叠区间问题,往往是和贪心策略有关,因此根据右端点排序,维护end变量。用最少数量的箭引爆气球无重叠区…