getchar函数输入与缓冲区

简介: getchar函数输入与缓冲区

前言

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

一、

(1)缓冲区是什么?

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

586fe184660d43879ef45a053477060f.png4657127ca0be40879b46eac0247f020a.png

(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;
}

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

6001fbe80b964533bc08783d3bbbbb29.jpg

我们输入密码之后,在缓冲区中不只是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;
}

b8e5bace4f964a9ea5992f49128d1924.png

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

338a82be3306493089769b2315536fd2.png

当输入的密码中包含了空格,因为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;

50fd83755f4043fca8c77844acf1755a.png

将scanf后的getchar()换成

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

{

;

}

总结

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

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

目录
相关文章
|
6月前
|
存储
文件的顺序读写——顺序读写函数——fgets、fgetc、fputs、 fputc
文件的顺序读写——顺序读写函数——fgets、fgetc、fputs、 fputc
79 0
|
6月前
|
存储 C语言
c语言获取终端输入字符串的函数scanf,gets,fgets
c语言获取终端输入字符串的函数scanf,gets,fgets
140 1
|
22天前
|
存储
底层文件操作的各种函数(二)------printf,fprintf,sprintf,scanf,fscanf,sscanf的对比以及文件缓冲区
底层文件操作的各种函数(二)------printf,fprintf,sprintf,scanf,fscanf,sscanf的对比以及文件缓冲区
37 2
|
5月前
格式化输入──scanf()函数
【6月更文挑战第24天】格式化输入──scanf()函数。
103 5
|
5月前
|
C语言
用getchar和putchar读/写字符
用getchar和putchar读/写字符
32 0
|
6月前
|
存储 C语言
用scanf函数输入数据
用scanf函数输入数据
61 1
|
6月前
|
存储 Java C语言
C 语言用户输入详解:scanf、fgets、内存地址解析及实用指南
您已经学习了 printf() 函数用于在 C 语言中输出值。 要获取用户输入,可以使用 scanf() 函数:
89 0
|
存储 数据安全/隐私保护
scanf函数读取数据 & 清空缓冲区
scanf函数读取数据 & 清空缓冲区
342 0
|
人工智能
scanf函数与getchar函数区别
scanf函数与getchar函数区别
142 0
fgets(),strtod(),strnlen(),strcmp()函数记录
fgets(),strtod(),strnlen(),strcmp()函数记录