目录

一背景:

二 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]"。

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

scanf库函数的返回值相关推荐

  1. C语言scanf函数的返回值、scanf函数的安全版、在while条件中使用scanf函数

    scanf函数的返回值,是正确读取的项数:读入一个数,返回1,读入2个数,则返回2,如此: VC2012,先做一个测试程序: 提示出错: error C4996: 'scanf': This func ...

  2. scanf函数的返回值问题

    1.scanf()函数有返回值且为int型. 2.scanf()函数返回的值为:正确按指定格式输入变量的个数:也即能正确接收到值的变量个数. scanf("%d%d", & ...

  3. scanf函数的返回值以及在while循环中的应用

    我们刚开始学习C语言时,经常会使用scanf函数输入参数.但关于scanf函数的返回值你清楚吗? 一.scanf的返回值 scanf函数的返回值分为以下三种情况: 整形,例如我们在用scanf函数进行 ...

  4. C语言scanf()函数的返回值

    C语言scanf()函数的返回值 代码例子: #include<stdio.h> int main(){int num1=0,num2=0;int value= scanf("% ...

  5. scanf函数的返回值是什么?

    scanf函数的返回值与正确输入数据的个数有关,当输入有错误时,错误输入之前正确输入数据的个数即为scanf的返回值.简而言之,scanf返回值等于读取到正确数据的个数. 初学者可能会问:scanf函 ...

  6. C语言库函数的返回值的一般规则

    C语言库函数的返回值的一般规则 一.常见函数举例 1.判断函数 正确为1,错误为0 比如C语言中判断是否到达文件结尾函数 int feof(FILE *filepointer) 1.到达文件尾部 1 ...

  7. scanf( )函数的返回值

    当从键盘连续进行输入时用while,但是程序自己不会通过正常的输入结束. scanf("%d%d",&a, &b); 如果a和b都被成功读入,scanf()的返回值 ...

  8. C语言中scanf()函数的返回值

    c语言中简单的输入scanf函数和输出printf函数,我们经常使用,也很熟悉,但有时却还是会在这两个地方犯错. #scanf()函数 功 能: 执行格式化输入 用 法: int scanf(char ...

  9. [C语言]printf函数和scanf函数的返回值

    先来看一道题 #include<stdio.h> int main() {int a=43;printf("%d\n",a);return 0; } 看完嘴角疯狂上扬, ...

最新文章

  1. 2018-3-25论文(Grey Wolf Optimizer)自然界狼群的生活等级
  2. error LNK2001: 无法解析的外部符号 “void __cdecl cv::cvtColor
  3. Docker Caffe部署
  4. 全国计算机等级考试题库二级C操作题100套(第82套)
  5. 编辑视频贴纸软件_视频特效编辑软件下载-视频特效编辑器下载V10.9.93-西西软件下载...
  6. 有一定基础学python_有一定编程基础,有什么好的自学python的教程吗?
  7. windows 设置 rocketmq环境变量_RocketMQ 开篇
  8. python用matplotlib或boxplot作图的时候,中文标注无法正常显示,乱码为小方框的解决办法
  9. 上海2018计算机中级职称,2018中级职称评定申报要求
  10. 工业数据采集网关的特点及应用场景
  11. 小趣味:js编写斗地主规则(完整代码)
  12. 粒子群matlab工具箱,Matlab粒子群算法工具箱使用方法及实例演示
  13. jdk 配置出错could not open `C:\Java\jdk16\lib\amd64\jvm.cfg‘ 解决方案
  14. 《金山词霸2009 牛津版》插件工具加载
  15. IPD解读--华为500强的研发第一名,除了钱还有IPD
  16. 数据库查询时报IllegalArgumentException异常是什么原因?
  17. ISO 8601中周数的处理及 Joda-Time 的使用
  18. “省份、城市、区县” 三级联动数据
  19. JavaScript 编程题
  20. 6.S081-7中断(键盘输入+屏幕输出) - Interrupts

热门文章

  1. git 指令操作虚拟机操作
  2. 神经网络优化算法nag_数值算法组(NAG)向Java开发库添加了新功能
  3. cf大区服务器显示人数合区后,CF:各大区迎来合并,未来只有4大战区,看看自己属于哪个战区?...
  4. 蓝桥杯2017 B组C省赛真题 2017-10 k倍区间
  5. 烤仔建工 | 来红浪漫和漂亮姐姐Yanelis K歌吧
  6. 【学习设计模式6】单枪匹马只身一人——单例模式
  7. python将图片转动漫_如何将照片动漫化
  8. EditText getText
  9. MediaPlayer无法成功切换歌曲:setDataSource(FileDescriptor fd)的问题
  10. 在HTML中 ( )属于非成对标记符,第一单元练习.doc