对C语言scanf函数深入研究

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43776408/article/details/85737585

一.请看以下代码

#include<stdio.h>
main()
{
	int a,b,c;
	scanf("%d %d %d",&a,&b,&c);
	printf("%d %d %d",a,b,c);
}	

第一种输入:

1 2 3				

很明显这样输入符合要求,输出也是我们所预期的,接下来换一种输入方法

第二种输入:

1	2	3

这种输入每两个字符之间用一个tab隔开,明显与题意不符,但得到的结果确是我们预期的。

1 2 3

第三种输入:

1
2
3

每输入一个字符按下Enter键,得到的结果也是我们预期的。

1 2 3

综上所述,我们可以初步得到结论:使用scanf函数获取用户的输入时,无论我们怎样输入(哪怕我们每输入两个字符之间隔多个tab键),最终得到的结果都是我们所预期的。

二.不符合要求的输入得到符合要求的输出,But why?
用户的输入首先以ASCII码形式存到键盘缓冲区中,其中包括换行符(Enter),制表符(Tab),空白字符(Space)。对于上述第三种情况,用户的输入在缓冲区的存储形式是:

49 10 50 10 51 10			/*1的ASCII码是49,换行符的ASCII是10*/

当输入结束后,按下Enter键编译器开始编译,系统在内存中为局部变量a,b,c开启空间。然后调用scanf函数对缓冲区的数据进行读写。scanf函数首先读到49,然后scanf拿49分别与换行符(ASCII为10),制表符(ASCII码为9),空白字符(ASCII码为32)的ASCII码比较,发现49与这三个字符的ASCII码都不匹配,于是在变量a所占的内存空间写入49(相当于给a赋值)。接下来scanf继续读写,由于下一个字符是换行符,对应的ASCII是10,scanf就直接跳过转而读取下一个数据,当读到50时,由于50与上述三个字符对应的ASCII码都不匹配,于是将50写到变量b所占的内存空间中。按照上述过程scanf一直读到最后一个字符时,再继续读写时发现后面已经没有数据了,于是结束读写。

综上所述,我们输入的所有字符都会以ASCII形式先存到缓冲区中,scanf进行读写时只有当其遇到空白字符,制表符,换行符时停止读写,如果后面还有数据,那么scanf会继续读写。制表符,空白字符,换行符相当于函数中的间断点,在不含有间断点的区域函数存在映射关系,对应到scanf中,这种映射实质上给内存中变量赋值。所以不论哪种输入方式,最后的输出都会和我们所预期的一样。

三.既然scanf不读写换行符,制表符,空白字符,那这三个字符是不是就一直待在缓冲区?我们怎样在程序运行过程中控制它们?
答:第一个问题回答:不会,程序结束它们自然消失。
第二个问题回答:使用fflush函数。如何使用?请看以下代码

#include<stdio.h>
main()
{
	char ch;
	char ch1;
	int a;
	scanf("%d",&a);
	ch1=getchar();
	printf("%d %d",a,ch1);
}

假设我们输入5,按下回车后输出为:

5 10

具体为什么我在上面已讲过。大家可以看出,在程序结束之前,换行符始终待在缓冲区中,它对我们而言无任何用处,更重要的是它还占据了一定的缓冲区空间,对于大型工程而言会使程序的运行效率大大降低。为了解决这个问题我们加上ffiush(stdin)这行代码,这行代码的意思是清空键盘缓冲区,函数fflush里面的参数stdin代表的是键盘缓冲区。

#include<stdio.h>
main()
{
	char ch;
	char ch1;
	scanf("%c",&ch);
	fflush(stdin);
	ch1=getchar();
	printf("%d %d",ch,ch1);
}

首先我们输入A <换行>,它们以ASCII码形式存到键盘缓冲区中,经过scanf读写后,变量ch在内存中存储的的值为65,缓冲区中只剩下换行符的ASCII码,这时程序运行到fflush(stdin)这一行,然后清空了缓冲区。我们继续输入B <换行>,这时变量ch1在内存中存储的的值为66。

A
B
65 65
Press any key to continue

通过fflush()函数我们可以实现对缓冲区的控制,及时释放缓冲区空间,增加了scanf的读写速率,也提高了程序效率。

文章至此结束,感谢您的阅读。由于本人实力有限,文章的错误之处在所难免。如果您发现了文章的某一处错误可以选择在下方留言,我会重新修改。

展开阅读全文

没有更多推荐了,返回首页