用c写一个双向链表,结果在scanf上总是出现问题:明明得输入3次结果每次都是2次就结束了。调试也没有个所以然来,上网查了一下是输入缓冲区的问题。貌似不是第一次遇到这个问题,所以在这里小结一下。我是在ubuntu下进行的。
考虑下面的程序:
#include <stdio.h>
int main( void )
{
char i,j;
scanf("%c",&i);
scanf("%c",&j);
return 0;
}
本来得输入两次的,但是输入一个字符后回车,程序就退出了,原因在于回车(在linux下为/n,在windows下为/r/n)被当作字符送入输入缓冲区。第二个scanf直接从缓冲区读取这个回车赋值给j,所以不会等你输入第二个字符程序就退出了。验证一下:
#include <stdio.h>
int main( void )
{
char i,j;
scanf("%c",&i);
scanf("%c",&j);
if( j == '\n')
printf("yes\n");
return 0;
}
输入字符,然后回车,程序输出字符后会输出yes。
解决办法就是使用getchar吃掉这个换行符。
#include <stdio.h>
int main( void )
{
char i,j;
scanf("%c",&i);
getchar();
scanf("%c",&j);
if( j == '\n')
printf("yes\n");
return 0;
}
另外一种提到很多的就是用fflush(stdin),但是标准中并没有定义这个方法,而且我在使用fflush(stdin)时就没有刷新缓冲区的效果,输出还是下面这样:
所以还是不要用这种方法!详细的解释可以参考这篇文章
类型不匹配
上面的例子如果改成这样:
#include <stdio.h>
int main( void )
{
char a;
int b;
scanf("%c", &a);
scanf("%d", &b);
printf("a:%c\n",a);
printf("b:%d\n",b);
return 0;
}
输入a,回车后输入3,如下所示:
可见a、b的读取都是正常的,那么回车去哪了呢?
因为b是int类型的,而'\n'为char类型,二者类型不匹配,这时scanf会忽略这个回车符去读取后面的输入。
#include <stdio.h>
int main( void )
{
int a=33,b=44,d=55;
char c='t';
int i = scanf("%d%d%d",&a,&b,&d);
scanf("%c",&c);
printf("i:%d\n", i);
printf("a:%d\nb:%d\nd:%dc:%c\n",a,b,d,c);
return 0;
}
输入2,回车后输入a,最后回车,输出如下:
原因在于scanf如果遇到不匹配的输入就会忽略这个不匹配的参数及其后面的所有参数,去执行后面的语句。在这里,输入2之后应该再输入一个整数的,由于输入的a为字符类型,显然不匹配,那么scanf就跳过b、d直接执行下一条scanf了。
最后一个是空白符问题。
#include <stdio.h>
int main( void )
{
int i,j;
scanf("%d ", &i );
return 0;
}
这个程序得输入两个数才能结束,原因在于scanf会忽略空白字符(空格,制表符,换行符,回车符和换页符)去读取下一个输入。
输入两个数后,程序才会退出。