c语言快忘光了,来复习下scanf的原理,有错误之处请大佬谅解并指正!
c语言初级阶段比较重要的输入输出就是标准输入输出,我的环境是vscode,#include <stdio.h>正在其中。而scanf是其中最重要的。 在我们的os内存在一块缓冲区,叫做标准输入缓冲区(其实可以理解为一块内存)
观察手册不难发现,文档是这么描述scanf的:
函数的参数是各种类型的格式控制符,scanf会对传入其中的格式控制符进行一一的匹配,直到传入的参数类型不能正确完成匹配,返回一个代表该函数成功读取到的参数个数。
那么这与前面谈到的缓冲区有什么联系呢?
例如我们写段代码:
使用scanf读入键盘输入的三个数据,每个数据用空格进行分隔,当我们输入完第三个数据的时候,我们敲击回车(换行,\n)等待结果。换行的原因是,scanf是行缓冲机制,即不论我们怎么输入,输入什么数据,数据始终还是保存在我们的缓冲区内,尚未进行真正的IO操作。而当读到了换行符时才会进行真正的IO操作。
假设我们输入的是10 c 1.5;
实际上在缓冲区内的效果是这样的:
scanf的参数中第一个格式是%d,匹配整形数据10,scanf会从缓冲区中将10成功匹配上并且读走;
重点来了,第二个格式是%c,字符类型的数据。
不难理解,空格' '和换行‘\n’都是字符类型的数据。对于scanf来说,给%c进行匹配时,由于我们输入数据是用空格进行两两分隔,我们在输入时并未看到10后面有数据,但实际上我们用于分隔的空格‘ ’同样也是字符型的数据,因此此刻匹配的字符是空格‘ ’,也就是说scanf的%c,会匹配上空格。
但是值得注意的是,我们在scanf的两两格式控制中,也采用了空格,这使得我们使用这一空格“吃掉“了我们用于分隔的空格,使得接下来的‘c’可以成功匹配上%c。接下来的浮点数1.5,读取前由于空格并不是浮点数据,因此可以顺利完成匹配,浮点数匹配上1.5。
最终输出结果:
总结:当scanf进行匹配时,匹配%d整形,%f浮点数据之前,会“清空”缓冲区(实际上对于残留的空格和换行,由于无法匹配,便不予匹配,计算机术语称为阻塞,等待后来的输入)而匹配%c字符时,由于空格和换行都属于字符型,因此会对最终结果产生影响。