前言
介绍了解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在遇到空白符(如换行、空格等)会结束读取