概述
连续使用scanf 读取字符%c可能会读取出错。
使用scanf后使用gets会导致gets被跳过。
解决方法:scanf后加一个getchar()。
关于scanf还有一个问题,可以看我的另一篇博客scanf使用不当造成无限循环
两个scanf()的例子
int main(void)
{
char a;
char b;
printf("Please enter a letter:");
scanf("%c", &a);
printf("Please enter a letter:");
scanf("%c", &b);
printf("\n");
printf("a is %c, b is %c", a, b);
}
如果你运行上述代码,那么你会发现b显示不出来,就像下面的终端显示一样,这是因为scanf在读取用户输入的时候,遇到enter或者space键会结束,但是enter字符会被保存在数据缓冲区内,所以第二个scanf就会读取enter键,导致读取出错。
解决办法在前面就说了,紧接着上一行加一个getchar(),就会把这个缓冲区的enter给读取了,这样子缓冲区就空了,就可以正常读取下一个输入了。
Please enter a letter:a
Please enter a letter:
a is a, b is
gets()例子
下面的代码在循环中不断地获得一本书的title和auther还有value,第一个循环没有问题,但是第二个循环就会出错。
int main(void){
char title[100];
char auther[100];
float value;
for (int i = 0; i < 2; i++) {
printf("Please enter the title:");
gets_s(title, 100);
printf("Please enter the auther name:");
gets_s(auther, 100);
printf("Please enther the value of the book:");
scanf("%f", &value);
}
}
具体错误如下:
Please enter the title:a
Please enter the auther name:a
Please enther the value of the book:1
Please enter the title:Please enter the auther name:
按理说循环结束后,一切都应该从头再来,但是第二个要被读取的title却被跳过了,这是因为scanf在读取用户输入的时候,遇到enter或者space键会结束,但是enter字符会被保存在数据缓冲区内,所以当第二次循环的时候,第一个gets()会把enter读进去,但是gets()函数本身不会把enter键保留,所以就有了上面的冒号后紧跟着Please。
两个scanf连续读取 整型 或者 字符串 会怎么样?
答案:正常运行
学习这种小坑还是要主动一点,多想想,比如%c出了问题,那么就试试其他的会不会有同样的问题。
如果读取的是字符串和整型,那么scanf会比较智能的自动忽略enter,所以不会对读取造成影响,不信的话可以复制下面的代码试一下。
int main(void)
{
char a[10];
char b[10];
printf("Please enter a string:");
scanf("%s", a);
printf("Please enter a string:");
scanf("%s", b);
printf("a is:%s, b is: %s", a, b);
}