【C】getchar函数与其在缓冲区的应用

在这里插入图片描述
博客主页:心辛向荣
系列专栏:【从0到1,C语言学习】
一句短话:你若盛开,蝴蝶自来!
博客说明:尽己所能,把每一篇博客写好,帮助自己熟悉所学知识,也希望自己的这些内容可以帮助到一些在学习路上的伙伴,文章中如果发现错误及不足之处,还望在评论区留言,我们一起交流进步!😊
在这里插入图片描述


💻前言

🍁介绍分析getchar函数以及其在缓冲区的应用


💻目录

1️⃣getchar函数与缓冲区
2️⃣getchar清理缓存区


💻.1 getchar函数与缓冲区

首先我们知道是getchar是用来获取一个字符的,而对应的putchar函数可以用来打印一个字符
在这里插入图片描述
getchar函数的返回值是用户输入字符所对应的ASCII码,若遇到文件结尾(End-Of-File)或者读取时遇到错误则返回EOF(-1),且将用户输入的字符回显到屏幕。
当使用getchar获取一个字符的时候,其实它不是从我们的键盘上直接获取的,在计算机的内存内存空间中存在一个 缓冲区。
1.缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。
2.缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

看下面这段代码

#include<stdio.h>
int main()
{

	int ch = 0;
	
	while ((ch = getchar())!=EOF)
	{
		//printf("%c",ch);
		putchar(ch);//与printf打印一样的效果
	}

	return 0;
}

在这里插入图片描述
看程序的执行过程,实质上当我们从键盘上输入一个字符时,这个字符是先存放在缓冲区当中等待getchar进行读取;
当我们在键盘上敲入回车后,getchar便会读取缓存区中的一个字符,而敲回车换行进行输出,实际上敲回车又在缓冲区放入了一个\n,在下一次循环getchar会将这个\n读走,所以输出一个字符后便自动换行了;
当输入^Z(Ctrl+z)时,getchar读取后会返回一个EOF,循环结束(VS编译器中可能需要按三次Ctrl+z,算是VS编译器的一点小问题,其他的编译环境正常一次即可)。

在这里插入图片描述


getchar使用实例只打印数字字符,跳过其他字符的,代码如下。

#include<stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar())!=EOF)
	{
	
		if (ch<'0'||ch>'9')
		{
			continue;
		}
		putchar(ch);
		printf("\n");
	}

	return 0;
}

💻.2 getchar清理缓存区

看这样一个代码,输入一个密码,然后进行确认密码。

#include<stdio.h>
int main()
{
	int password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//假设密码是abcdef
	printf("请确认密码(Y/N):>");
	int ret = getchar();
	if (ret == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/21183cd73a604b72a77819ad8ddbf55e.png
看这里的运行结果,还没有输入Y/N进行确认,便已经输出了结果了
这里是因为我们在输入abcdef后,它只是在缓冲区等待进行读取,当我们在键盘上敲入回车后,在缓冲区放入了一个\n,scanf才会进行读取,要注意的是scanf在遇到空白符(如换行、空格等)会结束读取,所以scanf并不会去读取\n,getchar会将缓冲区中的\n读走进行判断结束了程序。
在这里插入图片描述
这里在scanf读走字符串后我们需要解决掉这个\n 才可以正常进行确认密码,也就是需要清理缓冲区


如果只是要清理上面的问题,我们只需要把缓冲区的\n清理掉即可,做法如下:

#include<stdio.h>
int main()
{
	int password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);

	getchar();//清理\n

	printf("请确认密码(Y/N):>");
	int ret = getchar();
	if (ret == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

在这里插入图片描述
这里在scanf后加了一个getchar,当scanf读取结束后,getchar接着就会把缓冲区的\n清理掉;但这个方法只是可以临时解决问题,存在很大的弊端,看下面这个运行结果
在这里插入图片描述
当输入的密码中包含空格,因为scanf遇到空白符会结束读取;而这时scanf后的getchar只能清理一个字符,后面的qwer\n就无法被清理而导致无法正常进行密码的确认,所以说这种方法有时候无法完全清理缓冲区,原因是这里的getcher只能实现一次清理,而如果我们可以实现多次清理就可以解决这个弊端。
下面是优化后的清理缓存区的代码。
将scanf后的getchar换成
while ((ch = getchar()) != ‘\n’)
{
;
}

这条循环语句会让getchar逐个清理缓存区的字符,直到将最后的\n清理掉循环结束.

#include<stdio.h>
int main()
{
	int password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	//getchar();
	int ch = 0;
	while ((ch = getchar()) != '\n')
	{
		;
	}
	printf("请确认密码(Y/N):>");
	int ret = getchar();
	if (ret == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

在这里插入图片描述


💻结语

各位小伙伴,看到这里就是缘分嘛,希望我的这些内容可以给你带来那么一丝丝帮助,可以的话三连支持一下呗(关注✌️点赞✌️评论✌️)!!!
感谢每一位走到这里的小伙伴,我们可以一起学习交流,一起进步!!!加油!!!

在这里插入图片描述

  • 38
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韵秋梧桐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值