getchar函数,缓冲区以及while ((ch = getchar()) != EOF)

Posted 再吃一个橘子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了getchar函数,缓冲区以及while ((ch = getchar()) != EOF)相关的知识,希望对你有一定的参考价值。

getchar函数——>从键盘读取字符 

 从cplusplus我们可以看到getchar函数的用法:

  • 从标准输入流里获取数据
  • 返回值类型是int型
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)
		putchar(ch);
	return 0;
}

那么你可能会问,getchar函数不是从键盘获取的数据是字符吗?为啥返回值类型是int类型?

  1. getchar函数,返回的值是字符,其实也是字符的ASCII码值(整数)。
  2. getchar函数,在读取结束或者失败的时候,会返回EOF,而EOF  ——>  end of file  ——> -1(整数)

想一想,这段代码的输出效果是什么呢?

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

并没有达到我们原本的预期效果,还没等到我们确认密码,控制台就自动显示出密码错误的内容。

 这是什么原因呢?那么我们就来说一说缓冲区的那些事~~~~~~~

sacnf和getchar先看缓冲区有没有数据,若有数据则先从缓冲区拿走数据若没有则从键盘输入数据

由于程序开始进行,到scanf之前缓冲区没有数据,于是键盘输入数据abcd\\n,存在缓冲区中,而scanf将abcd放在password中,只剩下\\n在缓冲区中,于是到了getchar也是先看缓冲区有没有数据,getchar检测到了\\n,于是getchar就不从键盘输入数据了,直接拿走缓冲区中的\\n

 那么这种场景怎么让getchar获取键盘输入呢?很简单,只要在getchar之前清空缓冲区就可以了

但是如果仅仅这样想,就思维太局限了,你比如假设我输入password是1234 56\\n呢?代码还是正常执行吗?

 发生异常了,那么这是怎么回事呢??

很简单,我画图来说明一下~~~~~~

那么你可能会想到,既然一个getchar清理缓冲区中的内容不够,那么我多放几个getchar不就好了吗?是这样的,那么问题在于我们放几个getchar呢?代码实现如下:

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

	//清理缓冲区所有内容
	while (getchar() != '\\n') {
		;
	}

	printf("请确认密码(Y/N):");
	int ch = getchar();
	if (ch == 'Y') {
		printf("确认密码正确!");
	}
	else
		printf("确认密码失败!");
}

 敲黑板,划重点:

//清理缓冲区所有内容
	while (getchar() != '\\n') {
		;
	}

可能你怕空格后面的字符清理以后丢失掉,那么你也可以在这个代码的基础之上改进一下,用一个变量存储下来

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

	//清理缓冲区所有内容,并把缓冲区内容先存储起来
	int temp = 0;
	while ((temp = getchar()) != '\\n') {
		;
	}

	printf("请确认密码(Y/N):");
	int ch = getchar();
	if (ch == 'Y') {
		printf("确认密码正确!");
	}
	else
		printf("确认密码失败!");
}

 敲黑板,划重点:

//清理缓冲区所有内容,并把缓冲区内容先存储起来
	int temp = 0;
	while ((temp = getchar()) != '\\n') {
		;
	}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

以上实例,仅基于正真的密码后面没有空格的情况下,如果密码中还真含有空格,则另做讨论,比如可能会用到gets来接收,而不是scanf

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

以上是关于getchar函数,缓冲区以及while ((ch = getchar()) != EOF)的主要内容,如果未能解决你的问题,请参考以下文章

清理缓冲区

while((ch=getchar())!='\n')是啥意思

多组数据输入写法:while(scanf(“%d“,&n) != EOF)和while(~scanf(“%d“,&n) ),以及while((ch=getchar()) != EOF)

getchar与putchar缓冲区以及字符串数组指针

为啥 `while ((ch = getchar()) != EOF)` 是常见的习语? [关闭]

读入优化