scanf()函数相信就算刚学C语言的朋友也知道,这是一个标准输入函数,它是从标准输入流stdin中读内容的。它的第一个参数是格式化字符串,后面跟着的存储内容的地址列表。
如果在全段代码中,只调用一次,且只获取一个变量内容的话,一般不会出现什么问题。不过在多次调用或者在一次调用中获取多个变量内容,代码往往会出现不符合预期的结果,下面由我给大家说明一下我自己在调用时出现过的问题,以及解决办法。
1. 多次调用scanf()函数,每次调用都获取一个字符变量内容,但是存储的字符变量内容与实际输入不符。
#include <stdio.h>
int main(int argc,char **argv)
{
char a = 0, b = 0;
scanf("%c",&a);
scanf("%c ",&b);
printf("a:%d, b:%d \r\n",a,b);
return 0;
}
从图中可以看到,b变量输入的字符与实际存储的内容不符,b变量应该输出的值为98,是b对应的ASCII码,但是输出的是10,是转义字符\n对应的ASCII码。说明如果是输入字符变量内容的话,回车键作为转义字符输入也有可能会被识别存储。那要怎么解决呢?
(1)改变第二次调用的格式化字符串,在前面加上\n,以便过滤掉第一次调用后输入的回车键转义字符。
#include <stdio.h>
int main(int argc,char **argv)
{
char a = 0, b = 0;
scanf("%c",&a);
scanf("\n%c",&b);
printf("a:%d, b:%d \r\n",a,b);
return 0;
}
(2)在第一次调用和第二次调用之间,多加一个getchar()函数调用。
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
char a = 0, b = 0, c = 0;
scanf("%c",&a);
getchar();
scanf("%c",&b);
printf("a:%d, b:%d \r\n",a,b);
return 0;
}
以上两种办法都可以解决这个问题。
2. 一个scanf()函数输入多个整型变量内容,并且连续调用,但是scanf()函数没有起到阻塞的作用。
#include <stdio.h>
int main(int argc,char **argv)
{
int a = 0, b = 0;
while(1)
{
printf("input two num:\r\n");
scanf("%d,%d",&a,&b);
printf("a:%d, b:%d \r\n",a,b);
}
return 0;
}
正常情况下,按照scanf()函数格式化字符串的格式输入整型内容,运行会正常。
但是如果输入整型内容与格式化字符串的格式不同,或者输入了非整型内容,从第二次调用scanf()函数开始,scanf()函数一直获取的都是这个非整型内容,而又与格式化字符串不符,直接终止这次函数调用,导致scanf()函数没有起到堵塞作用,输入内容与存储内容不符。如果在一个while(1)循环中调用scanf()函数,就可能会出现死循环,导致无法正常执行。
解决这个问题的办法也是增加调用一次getchar()函数。因为很难保证用户会按照要求输格式入,所以如果有更好的选择的话,还是少用scanf()函数吧,其他的非堵塞函数输入,如kbhit()函数与getchar()函数配合使用的设计就挺基础好学的。