scanf()函数连续输入数字,字符引发的小问题

一.问题引出:
 
偶然想起来的一个关于scanf函数的小问题,稍微不注意的话,还是很让人头疼的问题。
问题是由下面的一段小代码联想开来的:
int main()
{     
       int a;
       char b;
       scanf("%d",&a); 
       scanf("%c",&b);
       printf("a=%d\n",a);
       printf("b=%c\n",b);
       return 0; 
}
刚刚入门的人或是对scanf函数理解不深的人觉得这段代码没什么问题,但是当我们输入123+回车+a,没有得到预期的效果,结果是:
 a=123
 b=
  
 xiaoming@xiaoming-desktop:~/c$
      
而将        scanf("%d",&a); scanf("%c",&b);语句顺序互换后,输入a+回车+123:
 a=123
 b=a
 xiaoming@xiaoming-desktop:~/c$
      
结果正确,这个现象涉及到了scanf函数的缓冲机制问题,下面具体说明。
 
二.解释原因:
 
scanf()函数是格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。
其调用格式通常为:   scanf("<格式化字符串>",<地址表>);
对于一些基本用法及注意点,我这里就不细讲了。我想说的是 对常用的三种格式:
 
1.%d格式输入,默认分隔符是所有的空格、回车、制表;
 
2.%c格式输入,则按 ASCII字符考虑,无分隔符。可能会受到之前输入的影响。(上面的代码就是涉及到了这个问题)
3.%s 是 字符串格式,默认分隔符是所有的 white-spaces,输入后自动加入结束符"\0"。
 
其实scanf函数是从缓冲区读取数据(缓冲区中存储来自标准输入(stdin)的数据)。读取缓冲区的一个数据,就删除一个,直至缓冲区是空的,就阻塞之,等待键盘输入;并且scanf还能对数字输入忽略先导的空白符,如\n\t和空格等(注意,对字符输入并不忽略先导字符,这个也是很自然的道理,因为\n\t和空格在字符中都是合法的字符)。
 
三.             回到一开始的问题:
 
我们上面的代码恰恰由于,scanf没有忽略 在输入数字时得到的\n,在输入字符时,并没有忽略,所以,scanf直接从缓冲区读取\n到目的地址单元。大家可以验证一下:
      将printf(“b=%d”,b);(将b中字符输出ASII码)
得到结果为:
       a=123
    b=10
    xiaoming@xiaoming-desktop:~/c$
ASII码为10的恰好是\n.要解决这个问题,只需要在输入字符前清除缓冲区即可。
 
 

你可能感兴趣的:(scanf,字符,出错,连续输入)