scanf()函数的原理

想象输入设备(键盘)连接着一个叫“缓冲”的东西,把缓冲认为是一个字符数组。
当你的程序执行到scanf时,会从你的缓冲区读东西,如果缓冲区是空的,就阻塞住,等待你从键盘输入。
现在假设你的缓冲区里有:abcd\n1234\n  (其中\n是回车符)执行:scanf("%s",name);的时候,由于scanf是读数据直到看见空白符(空白符:指空格符、制表符、回车符)就停止的输入函数。所以执行后,把abcd存到了name中。缓冲区于是变成了 : \n1234\n
接下来的执行就有问题了,如果遇到了:scanf("%d",&number);怎么办?因为遇到了回车符,它并不是一个数字,所以scanf还有一个特性,就是忽略先导的空白符。不管是有几百个回车也好,几万个空格也罢,只要它们连续地出现在缓冲区的开头,就统统忽略他们。然后再读有意义的字符。于是1234被读入number。
回到刚刚,当缓冲区还是:\n1234\n的时候,如果遇到了:scanf("%c",&sex);应该怎么办呢?你说,那好办呀,不是说了忽略前导空白符吗?跳过回车读'1'呀!想法是好的,可这只针对你的程序这一种情况。如果我编写的程序就是统计用户输入了多少个回车呢?所以对scanf来讲跳过前导空白符有个例外,当参数是%c的时候,就把缓冲区的第一个字符返回回去,不管是什么。
这样的设计就有个问题,scanf对不同的参数表现出来的特性不一样。得承认,这是个缺陷,但不是说这样不好。
这样的设计至少把发现所有字符的机会交给了用户,设计者这样想:如果程序员使用了scanf("%c",..),那他就有必要知道这函数能把回车符读出来,至于程序员对回车符感不感兴趣,那就看他了,不感兴趣的话,程序员也一定知道该怎么处理。回到你的程序里。
当执行scanf("%s",name)的时候,要求你从键盘输入,于是你输入了"abc",然后“回车”。缓冲区里自然而然地是:abc\nscanf把abc拿走了,留下了\n,缓冲区里现在就剩下\n于是,下一个scanf ("%c",&sex); 想当然地读取了\n
- 关于scanf忽略前导空白符这一点,可以这样验证:
写个程序,用scanf()读数据,只要不是%c就行。然后输入的时候,随便输入回车、空格、制表符,然后“回车”确认。会发现程序依然提示等待你输入。就是因为它忽略掉所有前导空白符之后发现缓冲区是空的!于是乖乖地阻塞住,等待你输入。
- 关于scanf是直到看见空白符结束读取这一点,如果你是初学C的话,那么很快你就会遇到另一个函数,叫gets()。
程序里如果我们想一次读入一个英文句子:I am a student.如果你用scanf读的话,只能读出"I",想读出后面的东西要不断调scanf。此时需要用gets,这个函数不管是什么一律读进来,直到遇到回车符才停下。总之,各有各的用途,全都熟悉之后,才能在恰当的时候恰当地使用

转载于:https://www.cnblogs.com/liuweilinlin/p/3180249.html

c库函数之scanf相关推荐

  1. C库函数:scanf、fscanf、printf、fprintf、sprintf、 snprintf

    1. scanf 函数原型 int scanf(const char *format, ...);  功能:从标准输入 stdin 读取格式化输入. 2.fscanf 函数原型 int fscanf( ...

  2. C语言中耳熟能详的printf与scanf

    没有什么比时间更有说服力了,因为时间无需通知我们就可以改变一切了.---余华<活着> 大家好,今天给大家分享的是C语言中的scanf与printf函数,一提起这两个函数,大家可能觉得这不就 ...

  3. scanf()格式化输入

    参考资料: 菜鸟教程:C 库函数 – scanf() | 菜鸟教程 (runoob.com)https://www.runoob.com/cprogramming/c-function-scanf.h ...

  4. c语言中不带任何修饰符的浮点变量,江苏省计算机等级考试二级C语言笔试辅导题目...

    <江苏省计算机等级考试二级C语言笔试辅导题目>由会员分享,可在线阅读,更多相关<江苏省计算机等级考试二级C语言笔试辅导题目(155页珍藏版)>请在装配图网上搜索. 1.1 江苏 ...

  5. 【STM32】【STM32CubeMX】STM32CubeMX的使用之三:UART串口通信

    文章目录 前言 1.系统配置 2.实现收发 2.1.重写函数实现printf.scanf.getchar函数的使用 2.2.调用HAL库函数实现串口收发 2.2.1.串口收发函数一览 2.2.2.串口 ...

  6. 【STM32】HAL库 STM32CubeMX教程十四---SPI

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 在我们的HAL库中,对硬件SPI函数做了很好的集成,使得之前SPI几百行代码,在HAL库中,只需 ...

  7. 三,标识符(identifier)讲解

    标识符的类别 一,系统预定义标识符 顾名思义,系统预定义标识符就是系统预先定义好的一些单词,例如如下的主函数 main~,库函数名scanf和printf等,与关键字不同的意义就是:系统预定义标识符号 ...

  8. 蓝桥杯嵌入式基于STM32G4的模块总结【HAL库】【省赛】

    文章目录 前言 硬件资源 下载方式 模块总结 时钟树 LED灯 键盘 LCD USART串口 EEPROM MCP4017可编程电阻 ADC DAC 测量PWM频率和占空比 定时器生成PWM波 RTC ...

  9. SAMSUNG S3C2440的简易BootLoader ㈢

    SAMSUNG S3C2440的简易BootLoader ㈢ 2010年06月05日 [b]SAMSUNG S3C2440的简易BootLoader ㈢[/b] [b][/b] [b]第三部分:源代码 ...

最新文章

  1. os和sys模块的常用方法
  2. springboot自动配置的原理_SpringBoot自动配置原理
  3. jQuery1.3.2 源码学习 -2 两个重要的正则表达式
  4. git 命令详解和常见问题解决
  5. 《LINUX与UNIX SHELL编程指南》学习笔记
  6. 1.6_quick_sort_快速排序
  7. [bzoj1510][POI2006]Kra-The Disks_暴力
  8. mc服务器tp到指定,我的世界怎么把别人tp到指定地点 | 手游网游页游攻略大全
  9. 结对编程之设计电梯控制程序
  10. 慎用某60软件清理垃圾,导致三星SSD T5不识别了,折腾了一下午,终于弄好了
  11. 努比亚android P的功能,努比亚Z17Android P 正式版已开启小批量FOTA推送
  12. 多年录制游戏的心得分享
  13. matlab对数组中的某一列进行排序
  14. win10和win7哪个好用_Win10和Win7到底哪个好用(真实评测)
  15. 边云协同的优点_关于边缘计算和边云协同,看这一篇就够了
  16. 如何把旧电脑游戏数据迁移到新电脑?
  17. 【数据结构】一元多项式
  18. Kafka实现淘宝亿万级数据统计
  19. cannot be cast to javax.servlet.Servlet 解决
  20. HackRF实现GPS欺骗教程

热门文章

  1. 【DDLC(心跳文学部)mod版分享】
  2. 董明珠今晚开启抖音直播首秀;百度在美国遭集体起诉;京东小程序正式发布 | EA周报...
  3. TensorFlow入门(十-I)tfrecord 固定维度数据读写
  4. iPhone手机屏幕尺寸(分辨率)
  5. 从清洁工到斯坦福教授,一路开挂的她近日再当选美国国家医学科学院院士!...
  6. GSYVideoPlayer 视频播放器 GSYVideoPlayer
  7. 微信小程序 - TGit版本控制
  8. izone成员_PRODUCE48女团将出道,IZONE成员团内担当无责任预测!
  9. android Telephony学习 --- 第七篇 android7.0 来电(MT)流程
  10. echo重定向和cat重定向