目录
注: 涉及的问题在c或c++中均会出现,给出的解决方案也均能在c或c++中使用
问题代码举例
#include<stdio.h>
void main()
{
int a;
char c;
printf("请输入一个整数:");
scanf("%d",&a);
printf("请输入一个字符:");
scanf("%c",&c);
printf("( a=%d,c=%c ) \n",a,c);
getchar();
}
运行结果是,在输入了数字,按下回车后,没有等用户第二次输入,scanf("%c",&c);就执行完了
相信这是个是困扰过很多入门学习c/c++新手的一个问题。
原因分析
windows下,键入回车相当于输入了两个字符:回车符 '\r' (013 ASCII) 和 换行符 ‘\n’ (010 ASCII),所以第一次输入"xx"后,按下回车, 结果是向stdin输入了“xx”+ '\r' +‘\n’,
而scanf只吸收了"xx",回车符'\r' 用于告知scanf输入结束,换行符 ‘\n’ 就多了出来,仍在存在于标准输入流stdin中,
程序一旦运行到 scanf("%s",s)/ gets(s) /cin.getline() 等等输入语句,就会将输入流中的'\n'吸收。
因此没等用户键入新数据,输入语句就结束了。
解决方法
1.加一句getchar();
printf("请输入一个整数:");
scanf("%d",&a);
getchar(); //接收多余的'\n'
printf("请输入一个字符:");
scanf("%c",&c);
printf("( a=%d,c=%c ) \n",a,c);
2. scanf里面加一个空格
printf("请输入一个整数:");
scanf("%d",&a);
printf("请输入一个字符:");
scanf(" %c",&c);
printf("( a=%d,c=%c ) \n",a,c);
3. 清空标准输入流:fflush(stdin)
既然标准输入流stdin有多余的东西,那就把stdin清空一下就可以了。fflush函数专门做这个事情:
printf("请输入一个整数:");
scanf("%d",&a);
fflush(stdin); //清空标准输入流(stdin) fflush是stdio.h中的函数
printf("请输入一个字符:");
scanf("%c",&c);
printf("( a=%d,c=%c ) \n",a,c);
验证
解决方案1,2证明了 多余的字符只是一个,而不是两个,因为scanf()的输入格式是很严格的,如果多的字符超过两个,方案2必然不能奏效
为了证明多余的字符是换行符 ‘\n’ (010 ASCII) 我们再来实验一下:
#include<stdio.h>
void main()
{
int a;
char c;
printf("请输入一个整数:");
scanf("%d",&a);
printf("请输入一个字符:");
scanf("%c",&c);
printf(" a=%d,c=%d %d \n",a,c,'\n');
getchar();
}
输入2 按键回车,结果是:
可见,多余的字符有且只有'\n'
总结
三种方案在c或者c++下都能有效解决问题,很多初学者往往采用的是头两种解决方案,其实这两个方法有点偏方的感觉,第三种方案个人认为才是正解,强烈推荐fflush(stdin)。
PS:
其实这个问题只有msvc编译器(visual studio,visual c++等微软系IDE默认采用的编译器)编译的C程序,才会有问题,gcc/g++等GNU系编译器不会存在这个问题
因此,在Linux下编译运行不会有这个问题;而Windows容易有这个问题,但是若在Windows下使用MinGW编译器(QTCreateor、Clion)也不会有问题。