C语言:getchar( ) 函数详解

2023-11-14

一、getchar( ) 函数定义

getchar() - 字符输入函数,没有参数,从输入缓冲区里面读取一个字符 - 「 一次只能读取一个字符 」
EOF(-1) - end of file 文件结束标志 - 键盘上用 ctrl + z 实现

先查一下文档

image-20210507174102072

二、函数返回值

该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读取错误,则返回 EOF(-1)。所以 getchar() 函数返回值要用 int 整型变量来存储

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

运行结果:键盘上输入 abc\n,程序会在屏幕上输出 abc\n,输入 def\n,屏幕上会输出 def\n,当按下 ctrl + z 时程序结束运行

image-20210507171436005

这是为什么呢,程序的运行过程是这样的,getchar 有一个 int 型的返回值。当程序调用 getchar 时,程序就等着用户按键。用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字符 \n 也放在缓冲区中),当用户键入回车之后,getchar() 函数才开始从输入缓冲区中每次读取一个字符,getchar 函数的返回值是用户输入的字符的 ASCII 码,若遇到文件结尾 (End-Of-File) 则返回 -1 (EOF),并将用户输入的字符回显到屏幕,如果用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续 getchar 调用读取。也就是说,后续的 getchar 调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才等待用户按键。程序中 while 循环工作时,每一次循环 getchar() 就会从输入缓冲区读取一个字符,然后 putchar 输出,直到遇到了文件结束标志 EOF,循环判断条件为假,循环才结束

为啥用缓冲区呢?因为计算机CPU的处理速度是很快的,我们用键盘输入速度比不上CPU的处理速度,CPU就得等键盘输入完,很浪费资源,所以,当键盘输入完了,让CPU一次性处理,可以大大提高效率。

参考文章:getchar的使用


三、注意区分 getchar 和 scanf

对于 scanf 函数,'\n' 会触发 scanf 读取输入缓冲区的内容,但遇到 '\n' 或空格 ' ' 会停止读取,而 getchar 会直接读取 '\n' 和空格

// scanf多组输入,s,比如2008 6,使用下面语句,直到遇到'\n',停止读取
while(scanf("%d", &n) != EOF) { }

四、getchar 的使用实例

再来看一个和 getchar() 函数相关的实例:模拟密码输入

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	//输入密码
	printf("Input password:");
	scanf("%s", password);
	//确认密码
	printf("Comfirm password(Y/N):");
	int ch = 0;
	ch = getchar();
	//判断是否确认成功
	if (ch == 'Y')
	{
		printf("success!\n");
	}
	else
	{
		printf("defeat!\n");
	}
	return 0;
}

运行结果:

image-20210508223724390

输入密码 123456 之后,程序没有让我们确认密码,直接判断确认失败了,为什么会出现这样的结果呢?

当我们在键盘上输入密码并按下回车后,键盘缓冲区有 ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘6’ ‘\n’ 这些字符,此时 scanf 函数开始读取字符串 ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘6’ ,遇到 ‘\n’ 结束读取,这时运行到后面的 getchar 函数了,getchar 发现缓冲区里还有一个 ‘\n’ ,直接将其读取走并会返回给整型变量 ch,这时没有多余的 getchar 函数来接收字符 ‘Y’ 或者 ‘N’ 了,轮到 if 语句来判断时,ch 不等于 ‘Y’ ,输出 defeat!

那我们怎么改进,让字符 ‘Y’ 或者 ‘N’ 得以被接收呢,猜你已经想到了,那就是在 ch = getchar(); 语句前面增加一条 getchar(); 语句,来读取处理掉 ‘\n’ ,这样用来确认密码的那个 getchar 函数就可以接收字符 ‘Y’ 或者 ‘N’ 了

继续思考,如果我输入密码时多输了一些无用的字符,又该怎么样处理掉它们呢?比如输入 123456 abcdf\n

image-20210508230348909

需要写一个循环来读取处理掉无用的字符

修改后的代码如下:

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	//输入密码
	printf("Input password:");
	scanf("%s", password);
    //---清理缓冲区---
	int temp = 0;
	while ((temp = getchar()) != '\n')
	{
		;
	}
	//确认密码
	printf("Comfirm password(Y/N):");
	int ch = 0;
	ch = getchar();
	//判断是否确认成功
	if (ch == 'Y')
	{
		printf("success!\n");
	}
	else
	{
		printf("defeat!\n");
	}
	return 0;
}

运行结果:

image-20210508233110722
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言:getchar( ) 函数详解 的相关文章

  • LeetCode 1.两数之和

    题目链接 1 两数之和 思路分析 可以暴力枚举时间复杂度为 O n 2 O n 2 O n2 也可以用哈希表
  • RPA机器人来了, 你的饭碗还好吗?

    摘要 RPA正在席卷全球各行各业 从金融到医疗再到零售 多种重复有规律的工作流程正在被代替 从上世纪90年代到现在 RPA经历了怎样的发展历程 目前又是怎么样的现状呢 RPA 正在席卷全球 这是一个平常的星期二 你睁开睡眼惺忪的眼睛 迅速洗

随机推荐

  • 梳理Vue常考面试题型

    完整版在线阅读 http interview poetries top 1 对于MVVM的理解 MVVM是Model View ViewModel缩写 也就是把MVC中的Controller演变成ViewModel Model层代表数据模型
  • Linux03:CentOS7.5安装jdk1.8

    jdk下载地址 链接 https pan baidu com s 1GvcOgsIXn502aZC5yk1aDg 提取码 l16v 1 上传安装包 创建目录 mkdir p data soft 上传安装包 2 解压 tar zxvf jdk
  • Swagger常用注解强调点说明

    Swagger注解 常用注解 Api 用于类 一般用于controller类 表示 标识这个类是swagger的资源 显示在文档中 ApiOperation 用于方法 一般用于controller中的方法上 表示一个http请求的操作 Ap
  • Python爬虫的Selenium(学习于b站尚硅谷)

    目录 一 Selenium 1 为什么要学习Selenium 1 什么是Selenium 2 为什么使用selenium 3 代码演示 2 selenium的基本使用 1 如何安装selenium 2 selenium的使用步骤 3 代码的
  • Linux是什么,能干什么,在哪干?

    Linux就是个操作系统 它和Windows XP Windows 2003 2008什么的一样就是一个操作系统而已 Linux能干什么 它能当服务器 服务器上安装者各种企业应用 服务 比如 Web服务 apache 就是能架设网站的 数据
  • 程序员的自我修养(十二) -- Linux共享库

    共享库 从文件结构上来看 共享库和共享对象没什么区别 Linux下的共享库就是欧通的ELF共享对象 共享库的更新有两类 兼容更新 不兼容更新 版本命名 libname so x y z x 主版本号 库的重大升级 不同主版本号之间是不兼容的
  • 【高危】 Zoom Desktop Client for Windows <5.14.5 权限升级漏洞

    漏洞描述 Zoom 是一种用于视频会议 在线会议和远程协作的软件平台 Zoom Desktop Client for Windows 5 14 5 之前版本由于对数据的真实性验证不足 经过身份验证的攻击者可通过网络访将权限升级为 SYSTE
  • 核医学笔记-标准摄取值SUV计算

    SUV SUV值全称为标准摄取值 standard uptake value SUV 是pet在肿瘤诊断中常用的半定量指标 是指局部组织摄取的显像剂的放射性活度与全身平均注射活度 SUV 病灶的放射性浓度 kBq ml 注射剂量 MBq 体
  • Java五子棋详细步骤及完整代码

    五子棋 1 定义声明一个二维数组做棋盘 import java util Scanner public class Main public static void main String args 定义声明一个二维数组作为棋盘 int ga
  • c++primer 第十九章笔记 02运行时类型识别

    19 2 运行时类型识别 typeid运算符 用于返回表达式的类型 dynamic cast运算符 用于将基类的指针或引用安全地转换成派生类的指针或引用 将这两个运算符用于某种类型的指针或引用 当该类型含有虚函数 运算符将使用指针或引用所绑
  • sample函数—R语言

    简述 Sample函数从x的元素中提取指定大小的样本 使用替换或不替换 其使用格式为 sample函数 sample x size replace FALSE prob NULL 其中 x 一个可供选择的一个或多个元素的向量 或一个正整数
  • 用74LS165实现串口扩展并行输入口

    1 74LS165各个端口功能 SH RD 移位 装载数据 当为高电平时 在时钟信号下进行移位 当为低电平时 将并行输入口的数据送到寄存器中 CLK 时钟输入 A H 并行输入口 QH QH 串行输出口 GND 接地端 SER 串行输入口
  • SpringBoot 项目打包后获取不到resource下资源的解决

    SpringBoot 项目打包后获取不到resource下资源的解决 在项目中有几个文件需要下载 然后不想暴露真实路径 又没有CDN 便决定使用接口的方式来获取文件 最初的时候使用了传统的方法来获取文件路径 发现不行 查找资料后发现是Spr
  • Java垃圾回收(GC)机制

    一 为什么要垃圾回收 如果不进行垃圾回收 内存迟早都会被消耗空 因为我们在不断的分配内存空间而不进行回收 除非内存无限大 我们可以任性的分配而不回收 但是事实并非如此 所以 垃圾回收是必须的 哪些内存需要回收 哪些内存需要回收是垃圾回收机制
  • 亲密关系-【沟通日志】-如何不再重蹈覆辙

    大多数人会问 我要怎么克服眼前的困难 实际上应该问 哪些事已经做得很好 学会记录成长 就能固定成长 自我激励 过去的成功 会激发未来的成功 意识到自己已经走了多远 你才会更愿意继续去坚持 记录成长的工具 沟通日志 日期 年 日 每日记录 1
  • 2.Python数据分析项目——旅游景点票价预测

    1 总结 流程 具体操作 基本查看 查看缺失值 查看数值类型 预处理 缺失值处理 填充 拆分数据 获取有需要的值 统一数据格式 数据分析 groupby分组求最值数据 seaborn可视化 预测 RandomForestRegressor
  • vite简单介绍和配置整理

    vite简单介绍和配置整理 一 介绍 Vite 法语 快的意思 是一个HTTP服务器 特殊的地方 可以在单文件中书写ES6语法 支持热更新 请求的内容才会被打包 更新 Rollup打包 二 配置 总的配置 import defineConf
  • MySQL 8.0 密码策略修改

    首次登录mysql 需要修改原始密码 mysql gt show databases ERROR 1820 HY000 You must reset your password using ALTER USER statement befo
  • Ground Rules

    Ground Rules 1 Ground rules ground ra nd n 地面 土 土地 土壤 v 触海底 使停飞 阻止 起飞 罚 儿童 不准出去玩 adj 磨细的 剁碎的 rule ru l n 规则 统治 控制 管理 v 统
  • C语言:getchar( ) 函数详解

    文章目录 一 getchar 函数定义 二 函数返回值 三 注意区分 getchar 和 scanf 四 getchar 的使用实例 一 getchar 函数定义 getchar 字符输入函数 没有参数 从输入缓冲区里面读取一个字符 一次只