scanf老是出错?带你详细解决输入缓冲区问题

news2024/11/25 14:34:05

文章目录

  • 1.前言
  • 2.getchar 和 putchar
  • 3.缓冲区问题
    • 3.1先观察一个代码
    • 3.2输入缓冲区
    • 3.3清除缓冲区
  • 结尾

1.前言

我们一般在进行输入输出的时候,就会用到 scanf / printf并且根据格式指定可以输入输出各种类型的数据。可以输入整形,字符,浮点型等其他类型的数据。

今天呢我先给大家再介绍一下 getchar 和 putchar.

2.getchar 和 putchar

getchar呢是读取一个字符,并且只能读取一个字符。putchar呢则是输出一个字符。

我们要学习getchar 和 putchar也很简单

  • 首先getchar获取一个字符后会返回过来,我们就定义一个整形变量 ch 来接收它,然后再用putchar把接收的值打印出来即可。
int main()
{
	int ch = getchar();
	putchar(ch);

	return 0;
}

在这里插入图片描述

  • 可能有人会问 getchar返回类型为什么是 int 类型,不是 char 类型。
  • 因为getchar读到字符后,它会把字符的ASCLL码值返回来。所以用整形接收
  • 还有一个点,getchar这个函数正常读取到字符的时候返回的是字符的ASCLL码值,但是它读取失败时返回的是 EOF,也就是 -1(整形)。整形的接收最好用int。ASCLL码的范围是 0 ~ 127
  • 大家可以通过这个网站搜索各种函数cplusplus.com
    在这里插入图片描述

3.缓冲区问题

3.1先观察一个代码

我们先来看一个代码:

这串代码的意思就是读取一个字符,然后输出一个字符。如果没有读取失败,就一直进行循环读取。 按ctrl+z即可停下来。

#include <stdio.h>
int main()
{
    int ch = 0;
    while ((ch = getchar()) != EOF)
    {
       putchar(ch);
    }
    return 0;
}

在这里插入图片描述

3.2输入缓冲区

上面这个代码看似很简单,其实逻辑是很复杂的。

我给大家介绍下它是怎样工作的:

  • 当我们第一次运行的时候,它会等待让我们进行输入。
  • 大家注意:像 getchar 和 scanf 是让我们输入数据的,但是这个输入数据是从键盘上拿吗?其实并不是。其实中间存在一个输入缓冲区。

在这里插入图片描述

  • getchar 和 scanf 首先去看输入缓冲区中有没有东西存在当我们第一次读取的时候去看输入缓冲区里没有东西,怎么办呢?这个时候就需要我们从键盘输入数据到我们的缓冲区里面
  • 第一次我们向输入缓冲区输入了一个A,并按下 回车键。回车其实就是 \n。第一次 getchar 把A读走,然后putchar把它输出。但是第二次进入循环,输入缓冲区中存在一个 \n,而 \n 不等于EOF,所以getchar就把 \n读走了,putchar 输出的时候就进行了一次换行。

3.3清除缓冲区

上面介绍的有什么用呢,其实它的用处还蛮多的。一般可以用来清空缓冲区。

看个代码:

  • 这个代码就是让我们输入密码,并判断密码对不对。若密码正确,则输入Y。
int main()
{
	printf("请输入密码:>");
	char password[20] = { 0 };
	scanf("%s", password);
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}
  • 我们先随便输入一个密码

在这里插入图片描述

我们发现,它并没有等我们确认密码就确认失败了。那这个代码哪里出了问题呢?

在这里插入图片描述
我们来一步一步分析

  • 开始输入缓冲区是空的,我们输入一串密码到输入缓冲区,并按下回车。scanf 会将 \n 之前的字符都读取走。当 getchar 要读取字符的时候,由于输入缓冲区不为空,所以 getchar 就把 \n 给读取走了。所以直接就进行了判断,而 \n 又不等于 Y ,所以就确认失败了。

所以我们想正确的进行这个代码,是不是要在 scanf 输入之后将输入缓冲区清理掉

  • 怎么清理掉缓冲区呢?我们在 scanf 后面单独加一个 getchar 是不是就可以把 \n 读走呢?

在这里插入图片描述

我们发现确实可以了。当我们到这里的时候,可能有的同学就觉得他学会了,实际上还差一点,我们再测试一下:

在这里插入图片描述

我们发现又确认失败了,原因很简单,这一次缓冲区里面放的不仅仅是 \n 了。

在这里插入图片描述

  • scanf 读取的时候默认的特点是读取到空格结束,scanf 把里面的123456读走了,第一个 getchar 把空格清理走了,但是缓冲区后面还放着 abc\n 呢,下一个 getchar 把 a 读走了,所以也确认失败
  • 我们发现一个 getchar 处理不完缓冲区的所有东西,所以我们可以写一个循环来清理缓冲区。当 getchar 读到的字符不等于 \n 我们就让它继续读。直到读取到 \n 我们就让它停止,这时缓冲区也就清理完毕了。
int main()
{
	printf("请输入密码:>");
	char password[20] = { 0 };
	scanf("%s", password);
	//清理缓冲区
	while (getchar() != '\n')
	{
		;
	}
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

在这里插入图片描述

注:也可以用 gets 和 scanf("%[ ^ \n]",str) 读取带空格的字符串,但是我们还是要弄懂缓冲区的原理。

结尾

所以当以后大家做这种输入输出的时候很奇怪,怎么这个地方出问题了,怎么我还没有输入就停止了,这个时候我们就要学会去分析,是不是缓冲区出了问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/471988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【元分析研究方法】学习笔记4.评估研究的质量

评估研究的质量 该步骤的作用该步骤中需要注意的问题该步骤中知识点1&#xff1a;判断编码的分类方式该步骤中知识点2&#xff1a;统计识别异常值 参考来源&#xff1a;库珀 (Cooper, H. M. )., 李超平, & 张昱城. (2020). 元分析研究方法: A step-by step approach. 中国人…

SpringBoot的事务与锁

在一人一单问题里&#xff0c;为什么加了事务还是会出现一人下多单呢&#xff1f; 本质的原因是&#xff0c;我们使用Java的对象锁&#xff0c;可以保证临界区只有一个线程访问&#xff0c;但是这和SpringBoot里加Transactional注解不是等价的。数据库里的事务保证的是要么全部…

ChatGPT+Word的智能化文字生成和应用

在Word中引入OpenAI代码需要使用VBA编辑器。以下是在Word中引入OpenAI代码的步骤&#xff1a; 打开Word文档&#xff0c;按下Alt F11键打开VBA编辑器。 在VBA编辑器中&#xff0c;选择“插入”菜单&#xff0c;然后选择“模块”。 在新建的模块中&#xff0c;将OpenAI代码粘…

【教学类-35-01】(256*256*256)RGB色卡图片

作品展示&#xff1a; 背景需求&#xff1a; 甲流传染病&#xff0c;班级来了三位孩子&#xff0c;他们玩折纸的时候讨论&#xff0c; 09号问&#xff1a;“绿色和蓝色混合是什么颜色&#xff1f;” 08号问&#xff1a;“绿色加蓝色加浅蓝合在一起是什么颜色” 17号说&…

逆向学习X64DBG

目标游戏&#xff1a;焰影神兵 目的&#xff1a;更改玩家名称&#xff08;中文名称&#xff09; 使用X64dbg可以快速搜索游戏人名&#xff0c;所以本次逆向使用该工具进行工作。 原来的名字&#xff1a;平家物语 现在我们想改成&#xff1a;源氏物语。所以打开X32/64dbg 附…

免费域名申请

title: 免费域名申请 20230428153405|left &#x1f308;Description&#xff1a; ​ 本文将介绍如何免费申请域名&#xff0c;在最近的折腾中发现&#xff0c;域名真的很重要&#xff0c;不然好多服务是无法访问的。 备注&#xff1a;由于freenom基于技术原因&#xff0c;暂时…

感知机学习

定义 感知机&#xff1a;假设输入控件&#xff08;特征空间&#xff09;是 X ⊆ R n \mathcal{X} \subseteq \mathbb{R}^n X⊆Rn,输出空间是 Y { 1 , − 1 } \mathcal{Y}\left\{1, -1\right\} Y{1,−1},输入 x ∈ X \mathbf{x}\in\mathcal{X} x∈X表示实例的特征向量&#x…

使用Pano2VR实现背景音乐、放大/缩小、旋转、缩略图和直线/立体/鱼眼模式等

内容简介 本文在文章《使用Pano2VR实现客厅VR效果》基础上&#xff0c;增加背景音乐、放大/缩小、旋转、缩略图和直线/立体/鱼眼模式等&#xff1b;效果如下图&#xff08;为了可以上传缩小屏幕&#xff0c;属于PC端运行&#xff09;&#xff1a; 实现过程 1. 运行Pano2VR软件后…

【初学人工智能原理】【1】一元一次函数:感知器如何描述直觉

前言 本文教程均来自b站【小白也能听懂的人工智能原理】&#xff0c;感兴趣的可自行到b站观看。 本文【原文】章节来自课程的对白&#xff0c;由于缺少图片可能无法理解&#xff0c;故放到了最后&#xff0c;建议直接看代码&#xff08;代码放到了前面&#xff09;。 代码实…

企业管理中,如何组建数据团队

数字化已经成为了当前时代的标志&#xff0c;也变为人们对未来社会发展的共识&#xff0c;一时间数字化相关技术、理念、应用都开始向各行各业普及。此时人工智能、云计算、大数据、互联网、物联网等的发展也越来越快&#xff0c;给人们的生活和企业的经营管理模式带来了深刻改…

设计模式 -- 原型模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

【问题解决】RabbitMQ启动出现epmd error for host xx.xx: nxdomain (non-existing domain)

问题描述 【k8s】或【普通容器】或【Linux】部署的RabbitMQ启动时出现了 epmd error for host xx.xx: nxdomain (non-existing domain) 错误&#xff0c;MQ无法启动成功。 其中 xx.xx 为无法解析的域名。 RabbitMQ官方还提到报错 Error during startup: {error,no_epmd_port}…

回归区间预测 | Matlab基于分位数随机森林算法(QRF)的回归预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 Matlab基于分位数随机森林算法(QRF)的回归预测,matlab代码。 基于分位数随机森林算法(QRF)回归预测,matiab代码,单变量输入模型。 评价指标包括:R2、MAE、MSE、RMSE和区间覆盖率和区间平均宽度百分比等,代码质…

【软件测试】自动化测试日志问题该怎么解决?测试老鸟总结方案...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

Leetcode力扣秋招刷题路-0801

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 801. 使序列递增的最小交换次数 我们有两个长度相等且不为空的整型数组 nums1 和 nums2 。在一次操作中&#xff0c;我们可以交换 nums1[i] 和 nums2[i]的元素。 例如&#xff0c;如果 …

为什么越来越多的人开始学习大数据了?

现在&#xff0c;在数字化转型的推动下&#xff0c;越来越多的企业意识到大数据的魅力&#xff0c;并不断在这个领域投入资金&#xff0c;Python大数据开发相关人才也备受青睐&#xff01; 大数据从业领域很宽广&#xff0c;不管是科技领域还是食品产业&#xff0c;零售业等都…

大数据行业就业前景怎么样呢

就目前的前景来看&#xff0c;大数据的发展的确的非常不错的~ 既然回答大数据的问题&#xff0c;那就让我们到用数据的方式来回答一下。大数据需求越来越多&#xff0c;只有技术在手不愁找不到工作。 先来看几个招聘网站的报告数据&#xff1a;Boss直聘发布的&#xff0c;今年…

Zynq-7000、FMQL45T900的GPIO控制(七)---linux驱动层配置GPIO中断输入

本文使用的驱动代码 (1条消息) FMQL45T900linux驱动外部中断输入ZYNQ-7000linux驱动外部中断输入资源-CSDN文库 在Zynq-7000、FMQL45T900驱动层也时常会用到对GPIO的控制&#xff0c;这里就针对实际使用的情况进行说明&#xff0c;首先根据之前的帖子确实使用GPIO编号 这里采…

从不均匀性角度浅析AB实验 | 京东云技术团队

作者&#xff1a;京东零售 路卫强 本篇的目的是从三个不均匀性的角度,对AB实验进行一个认知的普及,最终着重讲述AB实验的一个普遍的问题&#xff0c;即实验准确度问题。 一、AB实验场景 在首页中&#xff0c;我们是用红色基调还是绿色基调&#xff0c;是采用门店小列表外商品…

C++ 探索程序 详细解读程序在运行过程中都发生了什么

目录 头文件-源代码 头文件重复包含 问题 解决方案 程序生成过程 预处理Preprocessi 编译Compilation 汇编Assembly 链接Linking 编译期-运行期 编译期确定 运行期确定 编译期错误 运行期错误 类和对象 宏 宏的其他用法 头文件-源代码 头文件&#xff08;.h&am…