“C语言“——scanf()、getchar() 、putchar()、之间的关系
scanf函数说明

scanf函数是对来自于标准输入流的输入数据作格式转换,并将转换结果保存至format后面的实参所指向的对象。
而const char*format 指向的字符串为格式控制字符串,它指定了可输入的字符串以及赋值时转换方法。
简单来说给一个打印格式(输入数据格式),scanf函数会将打印数据格式的结果转换放到后面的实参变量当中。
比如下面的代码
#include<stdio.h>
int main()
{int a = 0;char ch = 0;double b = 0.0;scanf("%d %c %lf", &a, &ch, &b);printf("%d %c %lf", a, ch, b);return 0;
}

但scanf函数有一个缺点,就是scanf读取不了空格和回车等字符,当scanf读到这两个字符时,scanf会读取失败返回EOF,如果匹配错误也会读取失败返回EOF(比如应该是%d的数据转换到了char实参变量当中)。
EOF
EOF全名是:End of File 在<stdio.h>头文件中被定义为负值,即-1。

EOF的值不同编译器下值不同,在VS2019是-1
如果没有将头文件<stdio.h>包含到程序中,那么EOF就没有定义,程序不能编译和运行。
getchar和putchar

putchar的返回值是int,因为字符在程序存储的是ASCII码值,而且putchar只能打印字符,不能打印字符串,就是配合getchar()使用的。如果putchar成功获取了字符就返回所写字符,失败就返回EOF。
#include<stdio.h>
int main()
{putchar('a');putchar('b');putchar('c');return 0;
}


getchar返回也是int,参数是void,可有可无,getchar是从标准输入流读取字符(空格 回车都可以读取)并将其返回,如果读取失败就返回EOF。
比如
#include<stdio.h>
int main()
{int ch;while ((ch = getchar()) != EOF){putchar(ch);}return 0;
}

getchar如果缓冲区没有字符,getchar会等待我们的输入且摁下回车键才会打印在屏幕上。
配合putchar使用。
按下回车键后才在屏幕上输出对应字符。
ctrl+Z是将程序结束掉,退出了程序终止了代码循环。
crtl+Z相当于EOF。

为什么按回车键才会将字符输出到屏幕上呢?
C语言的输入输出一般会将读入的字符以及待输出的字符暂时保存在缓存中(缓冲区),当达到以下条件才进行实际的输入输出操作。
1.缓存已满 2.输入换行符(\n) 3.立即输出
对应方式称为1.全缓冲 2.行缓冲 3,无缓冲
键盘输入的内容不会直接给cpu处理打印在屏幕上 而是交给缓存 提高cpu运行效率。

getchar与scanf的关系
我们根据下图代码来分析getchar和scanf之间的关系
#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;scanf("%c", &ch);if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}
当程序运行时,我们刚输入完密码程序直接结束了,都没有确定密码的正确性,这是为什么呢?

当我们输入密码摁下回车键时,在缓冲区输入了1234\n,回车键相当于换行等于转义字符\n
第一个scanf读取了1234 第二个scanf读取了\n 直接填满了两个scanf的嘴巴,因此直接程序结束
并且结果为密码错误,当我们输入完1234摁下回车键那刻\n也被载入到了缓冲区,第二个scanf
定睛一看缓冲区有内容直接就读取走了。

解决办法
这时我们就要请出getchar给scanf擦屁股了,因为getchar能读取回车 空格等字符。
#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;getchar();scanf("%c", &ch);if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}

但如果有人在设置密码时写入了空格,而且scanf读取不了空格和回车字符,这时还是会出现代码判断错误导致运行结果错误。
我们直接用while循环搞一个一劳永逸的解决方案
直接使用循环清空缓冲区的空格 回车等字符
#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;while ((getchar()) != '\n'){;}
//以下两种写法都okscanf("%c",&ch);//ch=getchar();if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}

关系
输入b后摁下回车键形成\n
缓冲区载入的就是b\n
第一个scanf读取b 第二个scanf读取\n 因此程序结束语在第三行

输入a\n
scanf读取a getchar读取\n putchar输出a

输入a\n 第一个scanf读走a getchar读走\n
第二个scanf正常使用再次输入b\n putchar在下一行输出b

scanf读走as \nbxx是putchar读取的 a是第二个scanf读取的后面还有个\n
所以程序结束语在第4行。

总结
如果scanf输入过程中遇到空格 回车键等字符,scanf自己处理不了的读取字符时,就用getchar来解决,如果有多个处理不了的特殊字符就用while循环来处理(scanf处理不了的空格 回车键等特殊字符),配合getchar和putchar来给scanf的正常使用(擦屁股)。
相关文章:
“C语言“——scanf()、getchar() 、putchar()、之间的关系
scanf函数说明 scanf函数是对来自于标准输入流的输入数据作格式转换,并将转换结果保存至format后面的实参所指向的对象。 而const char*format 指向的字符串为格式控制字符串,它指定了可输入的字符串以及赋值时转换方法。 简单来说给一个打印格式(输入…...
Spring Boot3 Web开发技术
前期回顾 springboot项目常见的配置文件类型有哪些?哪种类型的优先级最高 yml properties yaml 读取配置文件里的数据用什么注解? value restful风格 RESTful 风格与传统的 HTTP 请求方式相比,更加简洁,安全,能隐…...
学习笔记:数据挖掘与机器学习
文章目录 一、数据挖掘、机器学习、深度学习的区别(一)数据挖掘(二)机器学习(三)深度学习(四)总结 二、数据挖掘体系三、数据挖掘的流程四、典型的数据挖掘系统 一、数据挖掘、机器学…...
highcharts的甘特图设置滚动时表头固定,让其他内容跟随滚动
效果图:最左侧的分类列是跟随甘特图滚动的,因为这一列如果需要自定义,比如表格的话可能会存在行合并的情况,这个时候甘特图是没有办法做的,然后甘特图的表头又需要做滚动时固定,所以设置了甘特图滚动时&…...
ElasticSearch 架构设计
介绍 ElasticSearchMySQLIndexTableDocumentRowFieldColumnMappingSchemaQuery DSLSQLaggregationsgroup by,avg,sumcardinality去重 distinctreindex数据迁移 ElasticSearch 中的一个索引由一个或多个分片组成 每个分片包含多个 segment(分…...
HTML---定位
目录 文章目录 一.定位属性概述 二.position 基础数值 三.z-index属性 网页元素透明度 练习 一.定位属性概述 HTML中的定位属性指的是用来控制HTML元素在页面中的位置和布局的属性,包括position、top、bottom、left和right等。 position属性指定了元素的定位方式&a…...
JVM高频面试题(2023最新版)
JVM面试题 1、JVM内存区域 Jvm包含两个子系统和两个组件。 1.1子系统 Class loader(类加载器):根据给定的全限定名类名(java.lang.object)来装载class文件到Runtime data area(运行时数据区)…...
webpack学习-7.创建库
webpack学习-7.创建库 1.暴露库1.1概念1.2验证1.2.1 不导出方法1.2.2 导出方法 2.外部化 lodash3.外部化的限制4.最终步骤5.使用自己的库5.1坑 6.总结 1.暴露库 这个模块学习有点坑。看名字就是把自己写的个包传到npm,而且还要在项目中使用到它,支持各种…...
MQTT - 笔记
1 Mosquitto 官网 https://mosquitto.org/ 2 Windows环境下安装配置Mosquitto服务及入门操作介绍 Windows环境下安装配置Mosquitto服务及入门操作介绍-CSDN博客 3 开源:MQTT安装与配置使用 【C++】开源:MQTT安装与配置使用_c++ mqtt-CSDN博客 4 一文搞懂Qt-MQTT开发...
Django 安装
各位小伙伴想要博客相关资料的话,关注公众号:chuanyeTry即可领取相关资料! Django 安装 在安装 Django 前,系统需要已经安装了 Python 的开发环境。 如果你还没有安装 Python,请先从 Python 官网 https://www.python…...
推荐一个vscode看着比较舒服的主题:Dark High Contrast
主题名称:Dark High Contrast (意思就是,黑色的,高反差的) 步骤:设置→Themes→Color Theme→Dark High Contrast 效果如下: 感觉这个颜色的看起来比较舒服。...
YCSB 测试表预分区
最近使用 YCSB 测试时,一直使用如下方法创建预分区: TABLE_NAME"usertable" REGIN_SPLITS$((510-1)) cat << EOF | sudo -u hbase hbase shell create ${TABLE_NAME}, cf, {SPLITS > (1..${REGIN_SPLITS}).map {|i| "user#{100…...
K8s 教程
一文让你全面了解K8s(Kubernetes) - 知乎 Install and Set Up kubectl on Linux | Kubernetes阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 留存一份地址...
python:改进型鳟海鞘算法(SSALEO)求解23个基本函数
一、改进型鳟海鞘算法SSALEO 改进型鳟海鞘算法(SSALEO)由Mohammed Qaraad等人于2022年提出。 参考文献:M. Qaraad, S. Amjad, N. K. Hussein, S. Mirjalili, N. B. Halima and M. A. Elhosseini, "Comparing SSALEO as a Scalable Larg…...
Hive-数据模型详解(超详细)
文章目录 一、Hive数据模型1. 概述2. 数据库和表(1) 创建数据库(2) 使用数据库(3) 创建表格(4) 查看表结构 3. 分区与桶(1) 分区(2) 桶 4. 数据加载与查询(1) 数据导入(2) 查询语句 5. 总结 一、Hive数据模型 1. 概述 Hive是基于Hadoop的数据仓库工具,它提供了类似…...
docker的常规使用总结
不安装docker下载镜像,或者下载异构镜像,模拟docker客户端 https://pull.7ii.win/ 1、启动docker服务 systemctl start docker 设置开机自启 systemctl enable docker 2、查看镜像 docker images --查看下载镜像架构 docker inspect 镜像名字 |…...
CSS 文字弹跳效果
鼠标移过去 会加快速度 <template><div class"bounce"><p class"text" :style"{animationDuration: animationDuration}">欢迎使用UniApp Vue3!</p></div> </template><script> export d…...
什么是动态IP?静态IP和动态IP有什么区别?
动态IP(Dynamic IP)和静态IP(Static IP)它是指在计算机网络中分配给设备的两种不同类型的IP地址。 动态IP是指每次设备连接到网络时,网络服务提供商(ISP)IP地址的动态分配。当设备重新连接到网络时,它可能会被分配到不同的IP地址。动态IP适用于传统的家…...
Linux 与 Shell
Linux系统的四部分:Linux系统的核心是内核。内核主要负责四种功能: 系统内存管理 操作系统内核的主要功能之一:内存管理。(物理内存 虚拟内存)内核通过硬盘上称为交换空间(swap space)的存储区…...
大数据-Hive练习-环比增长率、同比增长率、复合增长率
目录 🥙12.1 环比增长率 1. 概述 2. 公式 3. 示例 4.练习-需求:计算各类商品的月环比增长率 🥙12.2 同比增长率 1. 概述 2. 公式 3. 示例 4. 练习-需求:计算各类商品的月同比增长率 🥙12.3 复合增长率 1. 概述 2. 公式 3. 示例…...
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验 在嵌入式开发中,ADC(模数转换器)是连接模拟世界与数字世界的关键桥梁。无论是电池电压监测、环境光传感还是工业控制中的各种模拟量采集,AD…...
CrapFixer深度解析:为什么这个7年老工具依然是Windows优化的首选
CrapFixer深度解析:为什么这个7年老工具依然是Windows优化的首选 【免费下载链接】Crapfixer Cr*ap Fixer 项目地址: https://gitcode.com/gh_mirrors/cr/Crapfixer 在Windows 11和Windows 10系统中,你是否厌倦了无处不在的广告、烦人的数据收集和…...
3大策略掌握Avidemux视频编辑:从源码编译到专业级处理
3大策略掌握Avidemux视频编辑:从源码编译到专业级处理 【免费下载链接】avidemux2 Avidemux2, simple video editor 项目地址: https://gitcode.com/gh_mirrors/avi/avidemux2 Avidemux是一款开源跨平台视频编辑工具,专注于快速剪辑、编码转换和批…...
ncmdump终极指南:5分钟解锁网易云音乐NCM加密文件
ncmdump终极指南:5分钟解锁网易云音乐NCM加密文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾在网易云音乐下载了心爱的歌曲,却发现只能在特定客户端播放?当你想在车载音响、智能音箱…...
hot100 11盛最多水的容器
题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容…...
Unity Figma Bridge:设计-开发一体化协同的技术架构解决方案
Unity Figma Bridge:设计-开发一体化协同的技术架构解决方案 【免费下载链接】UnityFigmaBridge Easily bring your Figma Documents, Components, Assets and Prototypes to Unity 项目地址: https://gitcode.com/gh_mirrors/un/UnityFigmaBridge Unity Fig…...
用 Articraft 制作可动 3D 资产
如果你想做一个“能开合的台灯、能转动的风扇、能拉开的抽屉柜”,传统 3D 工作流通常意味着:建模、拆分部件、定义关节、反复调试、再导出到下游系统。 问题是,这类“可动对象”并不只是静态几何体,它们还需要语义化部件、合理结构…...
Bilibili神奇弹幕机器人:打造智能直播间的完整免费解决方案
Bilibili神奇弹幕机器人:打造智能直播间的完整免费解决方案 【免费下载链接】MagicalDanmaku 本仓库及所有相关项目已永久停止开发、维护和任何形式的分发。 项目地址: https://gitcode.com/gh_mirrors/bi/MagicalDanmaku 想要让你的B站直播间实现自动化运营…...
端侧AI算力瓶颈与优化企业格局解析
一、引言:端侧AI的发展困境与研究核心1.1 端侧AI的产业价值与普及现状端侧AI作为边缘计算的核心落地形态,正深度渗透工业制造、智能终端、车载电子、安防监控等领域。据IDC数据,2025年全球端侧AI芯片市场规模突破180亿美元,工业端…...
研究生你的救星来了
为了找一个研究方向的核心文献,我要同时打开知网、Web of Science、IEEE Xplore三个数据库,翻几十篇顶刊摘要,还要手动整理每个文献的研究方法、核心结论,熬到凌晨两点,结果还是理不清整个领域的研究脉络。直到上个月朋…...
