C语言 getchar()原理及易错点解析

一.getchar()系列
1.getchar()工作原理及作用
工作原理:getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了,第一次getchar()时,确实需要人工的输入,但是如果你输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。

实际上是 输入设备->内存缓冲区->getchar()

你按的键是放进缓冲区了,然后供程序getchar()
你有没有试过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你后头按的键没有存进缓冲区.
键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’\n’.要理解这一点,之所以你输入的一系列字符被依次读出来,是因为循环的作用使得反复利用getchar在缓冲区里读取字符,而不是getchar可以读取多个字符,事实上getchar每次只能读取一个字符.如果需要取消’\n’的影响,可以用getchar();来清除,这里getchar();只是取得了’\n’但是并没有赋给任何字符变量,所以不会有影响,相当于清除了这个字符.

作用1:从缓冲区读走一个字符,相当于清除缓冲区。

作用2:前面的scanf()在读取输入时会在缓冲区中留下一个字符’\n’(输入完按回车键所致),所以如果不在此加一个getchar()把这个回车符取走的话,接下来的scanf()就不会等待从键盘键入字符,而是会直接取走这个“无用的”回车符,从而导致读取有误。

2.使用getchar()清理回车\n

 1 #include <stdio.h>
 2 
 3 int main(void){
 4     char m[40];
 5     char n;
 6     printf("please input first str:\n");    //提示用户输入第一个字符串
 7     scanf("%s",m);                         //获取用户第一个输入字符串
 8     printf("you input str is :%s\n",m);    //输出用户的输入的第一个字符串
 9     printf("input second char :\n");        //提示用户输入第二个字符
10     scanf("%c",&n);                         //获取用户的第二个字符
11     printf("now you input second char is :%c\n",n);//输出用户输入的第二个字符
12     return 0;
13     
14 }

Output:

 

1 please input first str:
2 abc
3 you input str is :abc
4 input second char :
5 now you input second char is :
6 
7 Program ended with exit code: 0

 

问题:我们第一次输入abc后成功打印出来了you input str is :abc,但是执行到printf("input second char :\n");时,还没等到第二次输入就打印出来了。这是为什么??

原因:

  

其实在我们第一次输入并按下回车的时候,控制台一共获得了四个字符,分别是:a、b、c、回车(enter)。但是因为scanf()方法遇到非字符的时候会结束从控制台的获取,所以在输入’abc’后,按下 ‘回车(enter)’ 的同时,将’abc’这个值以字符串的形式赋值给了类型为 ‘char’ 的 ‘m’ 数组,将使用过后的字符串: ‘回车(enter)’ 保存在控制台输入的缓冲区,然后继续执行下一段输出代码,然后又要求用户输入。此时,因为上一次被使用过后的字符串被保存在缓冲区,现在scanf()方法从控制台的缓冲区获取上一次被使用过后的字符串,并只截取第一个字符: ‘回车(enter)’ ,此时控制台缓冲区才算使用完了。所以在看似被跳过的输入,其实已经scanf()方法已经获取了我们的输入了,这个输入就是一个 ‘回车(enter)’ 。

解决问题:
使用getchar()方法,清除掉abc后面的缓存(回车enter)。

 1 #include <stdio.h>
 2 
 3 int main(void){
 4     char m[40];
 5     char n;
 6     printf("please input first str:\n");    //提示用户输入第一个字符串
 7     scanf("%s",m);                         //获取用户第一个输入字符串
 8     printf("you input str is :%s\n",m);    //输出用户的输入的第一个字符串
 9     getchar();
10     printf("input second char :\n");        //提示用户输入第二个字符
11     scanf("%c",&n);                         //获取用户的第二个字符
12     printf("now you input second char is :%c\n",n);//输出用户输入的第二个字符
13     return 0;
14     
15 }

Output:

1 please input first str:
2 abc
3 you input str is :abc
4 input second char :
5 de
6 now you input second char is :d
7 Program ended with exit code: 0

3.使用getchar()清理缓存

文章结束时留了一个问题:如果在第一次输入ab后加一个空格再回车,又会出现原来的问题,即程序只输出了ab后就自动跳过下一次的输入之间退出了,控制台输出如下图所示。

转自他人博客

原因:

 在获取用户第一个输入字符串时,scanf("%s",&m);,我们用%s作为转换说明,%s的作用是“把输入解释成字符串。从第一个非空白字符开始,到下一个空白字符之前的所有字符都是输入。”所以scanf把输入的ab空格+回车就理解为ab+回车(ab后面没有空格),但是依然以ab空格+回车的形式存储在缓存区。

 

我们输入ab空格+回车,在缓存区是这样存放的:
其中,第三格存放的为空格键。
当程序运行完 getchar();后,只清除了第三格中的空格键,因为一次执行getchar();只清除一个缓存,留下了第四格中的回车键,因此再次出现了同样的问题。

解决问题:那么就是说只要运行两次getchar();,清除掉第三格和第四格就可以正常了。

#include <stdio.h>

int main(void){
    char m[40];
    char n;
    printf("please input first str:\n");    //提示用户输入第一个字符串
    scanf("%s",m);                         //获取用户第一个输入字符串
    printf("you input str is :%s\n",m);    //输出用户的输入的第一个字符串
    
    getchar();                              //第一次清除缓存
    getchar();                                 //第二次清除缓存
    
    printf("input second char :\n");        //提示用户输入第二个字符
    scanf("%c",&n);                         //获取用户的第二个字符
    printf("now you input second char is :%c\n",n);//输出用户输入的第二个字符
    return 0;
    
}

 

 

 

posted @ 2021-10-31 16:53  Colin_Cora  阅读(737)  评论(0编辑  收藏  举报