getchar函数输入与缓冲区


前言

介绍了解getchar函数及其在缓冲区中的应用

一、

(1)缓冲区是什么?

缓冲区又称为缓存,是内存空间的一部分,也就是说在内存空间中预留了一定的存储空间。这些存储空间用来缓冲输入或输出数据,这部分预留的存储空间就叫做缓冲区

(2)为什么要有缓冲区?

首先,把若干字符作为一个块进行传输比逐个发送这些字符节约时间。其次,如果用户打错字符,可以直接通过键盘修正错误。当最后按下Enter键时,传输的是正确的输入。

二、

1.getchar函数与缓冲区

当getchar获取一个字符的时候,其实它不是从我们的键盘上直接输入获取的,而是在计算机内存空间中存在的缓冲区中。

看下面这段代码:

#include<stdio.h>
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;
}

 我们输入ABCDEF回车之后,直接输出了“确认失败”,而并没有让我们输入(Y/N)来确认密码,难道就是并没有执行int ch = getchar();吗?

我们输入密码之后,在缓冲区中不只是ABCDEF,还有‘\n’。缓冲区中的字符是A B C D E F \n 。

这时我们要知道scanf不吃\n(换行符),所以当ABCDEF被scanf取走之后继续执行下一行,到int ch = getchar();时,getchar函数发现缓冲区没有清空,还有一位“\n”,它就直接取走了,继续向下执行,因为‘\n’并不=='Y',所以执行else语句,输出“确认失败”。

注意:scanf在遇到空白符(如换行、空格等)会结束读取

那么我们知道为什么出现问题了之后,我们该如何处理呢?

我们只需要把缓冲区中的‘\n'清理掉就可以了,做法如下:

2.getchar清理缓存区

代码如下(示例):

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

	return 0;
}

 这里在scanf后加了一个getchar(),当scanf读取结束后,getchar就会把缓冲区中残留的\n清理掉;但是这个方法只可以临时解决问题,存在很大弊端,看下面输入后的运行结果

 当输入的密码中包含了空格,因为scanf遇到空格会结束读取;这时scanf后的getchar只能清理一个字符,当把空格清理掉后,123后的’\n‘无法被清理而导致无法正常的密码确认。那我们该怎么办呢?

我们可以实现多次清理就可以完全解决这个弊端了,下面是优化后的清理缓存区的代码:

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

	return 0;
}

将scanf后的getchar()换成

while(getchar()!='\n') 

{

;

}


总结

缓冲输入用起来比较方便,因为在把输入发送给程序之前,用户可以编辑输入。但是,在使用输入的字符时,它也会给程序员带来麻烦。前面示例中看到的问题是,缓冲输入要求用户按下Enter键发送输入。这一动作同时也传送了换行符’\n‘,程序员必须妥善的处理掉这个麻烦的换行符。

另外也要记住 scanf在遇到空白符(如换行、空格等)会结束读取

猜你喜欢

转载自blog.csdn.net/weixin_74937672/article/details/128604934