一个常见的问题
#include <stdio.h>
int main()
{
int a;
char b;
float c;
printf("Please input an integer:");
scanf("%d", &a);
printf("integer:%d\n", a);
printf("Please input a character:");
scanf("%c", &b);
printf("character:%c\n", b);
printf("Please input a float number:");
scanf("%f", &c);
printf("float:%f\n", c);
return 0;
}
问题:为什么运行这个程序得不到下面希望得到的运行结果?
问题来源
我的想法是
该代码段运行时出现的问题是char类型变量b在输入时像是被“跳过”,直接输出结果,且输出内容直观上是一个“换行”。
按我的理解,是因为在第一条scanf语句scanf("%d",&a); 执行结束时用户按下回车键的时候,在产生回车的同时产生了一个换行符,比如输入9再键入回车,此时输入缓冲区中存的(以ASCII码存储)是39H 0DH 0AH(分别对应“9”,“回车”,“换行”) ,然后读取完39H和0DH后,不会马上清空换行符0AH,而是根据下面的第二条输入语句scanf输入的类型判断,有以下两种情况
1)如果第二次输入的是字符类型(char类型,控制格式%c)或字符串类型(控制格式%s),(本次讨论问题中d第二次输入数据类型为char类型),则将缓冲区中残余的0AH当作%c或%s的输入,故在屏幕中显示好像是“跳过”了该输入步骤,并且产生“换行”效果。
解决办法(亲测有效):
[1]在第一个scanf后,第二个scanf前加入getchar();语句,读取掉输入缓冲区残留的回车键;
[2]在第一个scanf后,第二个scanf前加入fflush(stdin);语句,清空整个输入缓冲区。
PS.初学者不建议马上太深入去看这两个函数,先弄懂主要用法就好,不然容易绕进去(๑•̀ㅂ•́)و✧
2)但是如果第二次输入的不是%c和%s这两种类型而是一些像是%d,%f之类的,因为这些类型的变量无法读取非”数“类型的数据,所以会自动抛弃缓冲区中残余的换行符0AH,所以这样的代码不会出错:
#include <stdio.h>
int main() {
int a;
char b;
float c;
printf("Please input a character:");
scanf("%c", &b);
printf("character:%c\n", b);
printf("Please input an integer:");
scanf("%d", &a);
printf("integer:%d\n", a);
printf("Please input a float number:");
scanf("%f", &c);
printf("float:%f\n", c);
return 0;
}