scanf库函数的返回值

目录

一背景:

二 scanf返回值规则

1.在格式字符串为用%d的情况下

(1)输入5 6此时scanf能正确读入的数据为两个,返回值为2

 scanf正确读入概念补充

(2)如果输入5 t此时能正确读入的数据为1个,返回值为1。

(3)如果输入1 2.5

(4)输入t 5,此时能正确读入的数据为0个,返回值为0。

2.在格式字符串用%c的情况


一背景

scanf是我们最开始接触的库函数,最开始接触的函数之一,当时就是记住1.在键盘上输入格式和要和代码那scanf中格式字符串(这个就是代码里scanf中双引号内的部分)的格式一样,2.存到变量,数组里要取地址,但是随着使用场景增多,我逐渐对scanf的使用产生了些疑惑,事情的开端是这样的,我们都知道scanf的返回值是正确读取到的数值,还可以利用这个返回值来结束循环,就像下面这样。

while (~scanf("%d",&b))
	{
		printf("%d", a);
		break;
	}

当scanf读取文件末尾,会返回-1,这个时候~就可以把(-1)的二进制取反为0,此时条件为假,跳出循环,对于应对多组输入的时候十分有用。但是就在我自己测试这个代码的时候,我却不知道如何输入数据才能让它返回-1,这个时候我就不免反思scanf的返回值规则。

二 scanf返回值规则

1.在格式字符串为用%d的情况下

scanf("%d %d", &a, &b)

(1)输入5 6此时scanf能正确读入的数据为两个,返回值为2

当我们输入完两个数字,此时敲击换行(enter)表示结束输入,数据进入缓冲区。可如果我们把换行放在输入两个数据前,比如输入第一个数据后换行,此时数据也会进入缓冲区,但是这个时候scanf读取的时候发现不够,你还得给我数据,此时就不会结束输入。如图

scanf还在苦苦等待中。

这个时候有没有同学想问scanf对于空格如何处理?

如上图,我就打一堆空格和换行夹着数据,我看scanf怎么处理,我想此时的scanf面对这个是有点错愕的,说这个前首先要补充的是:此时用%d类型转换时scanf会跳过所有的空白字符(换行,制表符,空格来读数据),没关系,我全都跳过,你该提供的没给够还是得给scanf,scanf跳过空白读取时知道你输入的不够,然后就会继续让你输入,这就是为什么换行在输入完两个数据前没有起到结束输入的作用,而空格却不会干扰scanf对数据处理的原因!

当我们都输入完后,此时我们输入的数据中夹杂的空格都不在缓冲区,应该被丢弃了,我们可以用下面来测试。在2和3之间有两个换行,3结尾还有个换行,如果2和3之间的换行被保留了,那我scanf就不会要求我们读入数据,但实际上我们还要输入个字符,这说明只有3结尾的换行被保留了。

还有就是我们说scanf在要读取整形数据的时候会跳过空白字符,但是如果我们格式里要空格而我们却没有空格,此时scanf会把这两个数字当成一个数据,而要你继续输入一个才够两个数据。

 总而言之,只要保证输入的格式字符串一致就能避免上诉问题,不要挑战规则!

正确读入概念:

scanf("%d %d %d", &a, &b,&e)

正确读入的数据判断我认为看两方面,1.我们输入进缓冲区中正确数据的个数   2.就是看scanf中%d的个数。注:不看要赋值的变量个数(大家可以试试,是不影响的)

为什么是两方面呢?我们可以这样想,scanf中%d的个数是他要的数据个数,但是如果scanf能正确读入就一个,如下面的例子(2),那这个时候返回值肯定看你有多少个数据是有用的嘛,如果你给的数据超过了scanf中%d的个数,这个时候scanf对于多了的数据就不会再读了,所以能正确读入数据分两方面,一方面是我要读多少个,还有一方面就是我有多少个数据是对的

(2)如果输入5 t此时能正确读入的数据为1个,返回值为1。

原因:当我们输入完两个数字(或者一个为字符,一个为数字),此时敲击换行(enter)表示结束输入,数据进入缓冲区,此时用%d类型转换时scanf会跳过所有的空白字符(换行,制表符,空格),scanf会判断数据类型,字符t不符合就不会scanf拿去赋值,而是留在缓冲区此时如果紧接连写多个scanf就会因为这个字符t不合要求多个返回值为零。

如图

同理上一个输入的换行也会留下来,如果你的三个scanf的格式字符串用的为%c,那scanf都会把这个换行记录下来,这个时候你发现我们只要输入一个字符就够了。

这里还要提一点,关于输入数据格式scanf代码中格式(也就是格式字符串)的问题,其实也就是输入的时候多个换行,空格的事,这个对于%d来说是无需理会的,谁叫%d可以跳过呢,就是这么任性,这个时候想必有读者想问了,标点符号呢?

首先第一%d不会跳过这个标点符号,(标点符号不是空白字符),然后就是如果出现输入格式不符合的情况,要逗号没写逗号,此时scanf读到此处会停止,不符合数据就留在缓冲区。

不要逗号,给了逗号,就和之前的情况要数字却给了字符,scanf用%d读取失败,将逗号字符和其之后的数据都留在了缓冲区。

 

我写着写着发现有个点一直被我忽略,就是我输入时我的输入法一直都是用中文,而我scanf格式字符串里面却是英文逗号的,居然不会出错,当然如果scanf格式字符串里面是中文,外面输入用英文会读取失败。我可以肯定地说同志们到探究这一步我们已经在沟里了,不用深究,我们在输入的时候眼尖点,可以看到编译器会更新一下我们的输入,我怀疑在这个地方对我们的输入做了处理,这就是为什么上面格式字符串中为英文逗号,而我们输入为中文逗号不会出错,反过来可能编译器就未对输入做处理。因为我们写代码一般都是英文嘛,可能设计编译器的人就默认代码里的都为英文,就帮我们把输入的都转为英文的格式,他可能没想到会有人反过来。

(3)如果输入1 2.5

此时scanf用%d读到非整数就停止,但不是读到2.5就不读了,而是在读取2.5的时候读到小数位就放弃读取,我当时看了是有点吃惊的,还有这种操作!所以它就把1和2拿走了,在缓冲区留下.5,当然此时返回值还是为2。

(4)输入t 5,此时能正确读入的数据为0个,返回值为0。

此时scanf需要一个数字而你却给了个字符,此时返回值为零。

那什么时候返回负一呢?vs中输入^z+换行连续三次才可以时其返回值为-1,此处貌似和文件尾定义和vs2019本身的bug有关,我就留之后解答吧,感觉一般我们也不会连续输入^z加换行。

2.在格式字符串用%c的情况

但对于%c,%s来说这个输入格式则必须要和格式字符串一模一样,因为对于%c来说空格也是字符,输入多了个空格可能scanf就把空格字符拿去赋值了,如果在格式字符串中多输入了个空格意义也不一样

此时格式字符串中没带空格,如果你输入2前多输入了个空格,空格就会被拿去赋值,此时打印出来变量c的内容就是个空格。

但是如果我们在格式字符串加个空格 ,如下图,不管我们在2前输入多少个空格都会被跳过,这就是在格式字符串加了空格的作用!

而空格对于用%s的scanf来说则是直接作为读取结束符号,除非用"%[^\n]"。

这篇时间间隔有点久,如果还有错漏请指正,谢谢大家!

  • 13
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小何只露尖尖角

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

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

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

打赏作者

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

抵扣说明:

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

余额充值