提出一个问题
先放一个代码:
#include <stdio.h>
int main()
{
int a;
char b;
scanf_s("%d", &a);
scanf_s("%c", &b);
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
在这里我使用visual studio2022学生版来运行一下这个代码
注意我只会输入一个字符
我们发现,虽然只输入一个1赋值给a,但是b也能输出!
为了解决这个问题,我们要更加深入了解一下原理~
缓冲区的理解
定义
缓存区是内存的一部分。在内存中预留一定的存储空间,在这些空间来输入和输出数据,这部分存储空间就是缓冲区啦。与之对应的,缓冲区被分为输入缓冲区和输出缓冲区。
如果无法理解“内存”,可以看看这个文章:
Q:为什么要有缓冲区?
- 减少磁盘读写次数
- 计算机对缓冲区的操作远远大于对磁盘操作速度
Q:缓冲区的类型
全缓冲/行缓冲/不带缓冲
Q:缓冲区会一直保留吗?
不一定,遇到以下情况会刷新
- 缓冲区满了
- 执行flush语句(flush:冲走)
- 执行endl语句(end line)
- 关闭文件
理解开头的输入输出问题
在我们输入“1”后在物理键盘上按了回车,当然这个回车被留在缓冲区了
计算机在读写给b时候因为没有输入就把刚刚的回车丢给b了
而回车的ASCLL码为10,所以输出的b就是字符10啦!
再次举例
这次我们依旧用上面的代码,但是输入“1 2”,也就是中间留了个空格
这样的话我们难以得到自己想要的b的值,于是我们就得使用fflush语句了
修改后的代码
#include <stdio.h>
int main()
{
int a;
char b;
scanf_s("%d", &a);
fflush(stdin);
scanf_s("%c", &b);
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
注意,这个只有在vs2015前的版本才能有效,得到以下结果:
现代版本解决缓冲区的问题
途径一
使用rewind(stdin);
不过还是看编译器,我的编译器就无法完成清楚缓冲区... ...
途径二
使用scanf("%*c"),这个代码作用就是清除缓冲区最后一个字符
Comments NOTHING