最近学C语言时遇到一个问题,就是scanf函数运行时我没有进行任何操作,结果它自己直接跳过了我输入数据这个环节,代码如下:

#include<stdio.h>
int main()
{
int a;char c;
scanf("%d",&a);
scanf("%c",&c);
printf("%d %c",a,c);
return 0;
}

按照我原来的设想,程序运行后我键盘输入一个数字0,回车后在输入一个字符A再回车,结果应该如下图所示。

为什么scanf语句不能执行直接跳过了?_scanf缓冲区

但是实际是我键盘输入一个数字0,回车后直接变成下图所示,没有进行第二个scanf函数的输入,程序就结束了。

为什么scanf语句不能执行直接跳过了?_scanf缓冲区残留问题_02

经过调试,我发现程序结束后第二个scanf函数其实是执行了,且符号变量c的值由‘\000’(‘\000’的ASCII值为0)变成了‘\n’(‘\n’是换行符,ASCII值为10),如下图所示。

为什么scanf语句不能执行直接跳过了?_scanf_03

经过查阅,我最终发现出现这种现象是因为我们在使用scanf键入数据时,数据不是直接赋给变量的,而是先储存在一个缓冲区,当我们按回车键时,再从缓冲区读取数据赋给变量,而我们使用scanf函数时按回车键后会自动产生一个换行符‘\n’(这也是我们用scanf输入数据时按回车键会自动换行的原因),这个换行符也会储存在缓冲区内。

当我们执行第一个scanf时没有影响,但在执行第二个scanf函数时会读取缓冲区中上一个scanf函数按回车后产生的‘\n’,然后赋给变量c,直接跳过了我们第二次输入数据的过程,所以我们看到最后会有换行的现象。

我认为因为‘\n’是一个单撇号括起来的字符,与我们定义的变量c数据类型一样在格式上属于单字符,所以才会误读,因为我发现如果第二个scanf语句输入数据的数据类型是整型、字符串或者浮点型的都不会出现这个现象。

具体解决办法:

1. 将第二个scanf语句改为scanf(“ %c”,&c);在%c的前面打一个空格即可,如下所示。

#include<stdio.h>
int main()
{
int a;char c;
scanf("%d",&a);
scanf(" %c",&c);
printf("%d %c",a,c);
return 0;
}


2. 在第一个scanf语句的下一行加上getchar语句,将换行符消耗掉,如下所示。

#include<stdio.h>
int main()
{
int a;char c;
scanf("%d",&a);
getchar();
scanf("%c",&c);
printf("%d %c",a,c);
return 0;
}