你怎么看待scanf()中%d的“吃空白”行为?

大家好!我是一只励志要翻身的小牛!


前言

上一期小编介绍了printf()scanf(),但是通过各位读者的反馈以及我近几天刷题中遇到的问题我觉得上期对scanf()的介绍还不够完善,需要对scanf()进行必要的补充说明。


一、scanf本质上是如何输入数据的?

上期介绍了输入缓冲区的概念,当我们通过输入数据后必须敲(回车),这样数据才会成功来到输入缓冲区(包括回车\n),接下来就是scanf()在缓冲区中按照指定格式提取所需数据。

二、scanf()提取%d数据的潜规则

1、%d前的“吃空白”行为

我们先看下面这个例子:

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d",&a,&b);
	printf("a=%d\n",a);
	printf("b=%d\n",b);
	return 0;
}
像%d%d这种格式说明符挨着的,中间没有任何分隔符,我们应该怎么输入?

如果两个整形符紧挨着的话,默认在输入数据时中间可以以任何空白字符作为分隔标志(包括-空格、回车符-\n、水平制表符-\t)并且不限数量。因此在我们输入紧挨着的整形数据时常常使用这种方法,使我们输入更加灵活。

那么这其中的原理又是什么呢?

原理:像%d这种输入,默认会把缓冲区中数字之前的空格和回车全部丢弃掉

也就是说:当我们输入%d这类整形数据时,当我们键入数据后,scanf()在提取整形数据时会自动 “吃掉“%d前所有的空白字符(包括-空格、回车符-\n、水平制表符-\t)直到提取到%d类型的整形数据。例如上述代码,我按照下图输入,依旧可以正常给变量赋值,能正确输出:👇

笔者在输入时,在数字1前敲了多个空格和制表符以及1个回车,在数字2前也是如此:

​​​​​​​​​​​​​​​

2、%d后追加(空白字符)产生的“吃空白”行为

原理:当参数为"%d "的时候,此时没有处理到结尾,scanf()会认为你要继续进行输入。然而你输入了空格或者回车,scanf()认为他们是分隔符,于是“吃空白”吃掉了。换句话来说,scanf()依旧在等待你的输入, 只有当你输入不是空白的字符以后,scanf()才会用它与参数字符串里面的空格比较。

也就是说:如果%d后面加上空格,在%d的匹配工作结束后,%d后面的空白字符开始工作,空白字符表示会“吃掉”所有%d之后的空白字符,也就是会丢弃缓冲区中%d后的所有空格、水平制表符和换行符,因此无论我们输入多少次回车都会被%d后的空白字符“吃掉”。如果此时想要停下来,这时候就需要输入一个非空白字符就能使空格吃空白的工作停下来。

但是这样做的话,很可能会产生bug,就是第二个非空白字符会被留在缓冲区中,下次输入时就会被读取,比如下面这种情况:(输入错位,产生bug)

因此不建议大家在%d后面追加(空白字符)容易产生bug,这些会产生歧义的代码尽量不要再工程中出现

总结

以上就是我对上期scanf()的一些补充,由于笔者学识尚浅,加之篇幅有限,如有不当之处,欢迎诸位指点。

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不摸鱼的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值