本节,在学习如何清空输入缓冲区之前,我们先来介绍一下“输入缓冲区”的概念。
输入缓冲区
所有从键盘输入的数据,不管是字符还是数字,都是先存储在内存的缓冲区中,叫作“键盘输入缓冲区”,简称“输入缓冲区”或“输入流”。我们先来看一个程序:
# include
int main(void)
{
int a, b, c;
scanf("%d", &a);
printf("a = %d\n", a);
scanf("%d", &b);
printf("b = %d\n", b);
scanf("%d", &c);
printf("c = %d\n", c);
return 0;
}
输出结果是:
1
a = 1
2
b = 2
3
c = 3
或者:
1 2 3
a = 1
b = 2
c = 3
从输出结果可以看出,不管是一个一个地输入:1(回车)2(回车)3(回车);还是三个数字一次性输入:1(空格)2(空格)3(回车),这两种输入方法的结果都是一样的。原因是从键盘输入的数据都会被依次存入缓冲区,不管是数字还是字符都会被当成数据存进去。但只有按回车,scanf 才会进去取数据,所取数据的个数取决于 scanf 中“输入参数”的个数。因此不在于怎么输入,可以存一个取一个,也可以一次性全存入进去,然后一个个取。
那么一次性全存进去,scanf 是如何取数据的呢?这就好比开闸放水,我们将水一次性全部放到闸里以后,开一次闸就放掉一点,开一次闸就放掉一点,直到放光了为止。开闸的动作就相当于调用一次 scanf,开闸的开关就是回车;每开一次闸放掉多少水,取决于 scanf 中“输入参数”的个数。
所以,输入的数据放在输入缓冲区中,先输入的排在最前面,后输入的依次往后排。如果 scanf 中“输入参数”的个数只有一个,那么我们调用一次 scanf 就把缓冲区中离出口最近的一个数据输出给 scanf,也就是把排在最前面的一个数据输出给 scanf。输出后,缓冲区中就没有这个数据了。
如果 scanf 中“输入参数”的个数为 n,那么就从排在最前面的开始,依次往后取 n 个数据输出给 scanf。没取完的仍旧放在缓冲区中,直到取用完毕为止。如果缓冲区中的数据全被取完了,但还有 scanf 要取数据,那就要再从键盘输入数据。
%d和%c读取缓冲区的差别
需要注意的是,对于 %d,在缓冲区中,空格、回车、Tab 键都只是分隔符,不会被 scanf 当成数据取用。%d 遇到它们就跳过,取下一个数据。但是如果是 %c,那么空格、回车、Tab 键都会被当成数据输出给 scanf 取用,例如下面这个程序:
# include
int main(void)
{
int a, c;
char b;
scanf(&