你真的了解scanf函数吗?

前言

scanf函数是C语言中最基本也是最常用的输入函数, 其基本功能为通过键盘实现数据的输入, 很多初学者在接触C语言时对它的了解并不多, 只能通过照猫画虎的方式进行简单的操作, 但在实际操作过程中, 由于自己的疏忽或各种实例的影响, 难免会出现漏敲、错敲、多敲字符的情况, 导致意想不到的结果。笔者也曾遇到同样的困惑, 去网上搜索解决方案, 大部分结果都非常零散, 或者治标不治本, 没有说明解决办法的原因和运行机制。
笔者经过探索和总结各种实例, 摸索出了scanf函数的一些运行机制, 目前完全可以解决遇到的各种问题, 现总结分享如下。

基本语法

首先简单介绍一下scanf函数的基本语法来帮助初学者更好地理解, 如果读者已非常熟悉,可以直接看下一部分。

通常情况下, 需要输入的类型有整型(%d)、浮点型(%f、%lf)、字符型(%c)、字符串(%s)。

#include<stdio.h>
int a=0;
scanf("%d",&a);

这是scanf函数的基本格式(以%d为例), "%d"为格式控制字符串, &a为赋值变量的地址(这是语法规定,必须用变量的地址), 要注意添加头文件<stdio.h>。
scanf函数也是有返回值的, 其返回值为成功读取并赋值的数据个数。
其他格式如显示宽度、对齐方式、保留小数位数等对接下来的内容用处不大, 网上的解释也非常详细, 这里便不再赘述。

运行机制

首先, 我们要明白, 在键盘和scanf函数之间存在一个媒介——缓冲区(可以简单理解为暂时存储数据的地方), 运行scanf函数时首先从缓冲区读取数据, 若缓冲区数据充足, 则不再需要从键盘输入; 否则需要从键盘输入数据, 这些数据被传到缓冲区后继续被scanf函数读取。需要特别注意的是, 我们在输入结束后会按’enter’键, 这一操作会为缓冲区增加一个字符’\n’。
其次,下面的表述中会多次出现’空白’二字, scanf函数将空格、\t(水平制表符)、\n均视为空白。

%d:

整型和浮点型的机制类似,这里以整型为例。
(1)%d读取时从第一个非空白字符开始, 遇到非数字字符结束
(2)%d读取时会自动吃掉第一个非空白字符前面的空白

这个例子中, 从键盘输入了"_ _ _6"( _代表空格),读取时自动将前面的空格吃掉了,将6赋值给了a

在这里插入图片描述
这个例子中, 输入"_ _ _a", 将空格吃掉后, 第一个字符是a, 由于是非数字字符, 读取结束, 赋值失败, scanf返回0

%c:

%c读取时不会吃掉空白字符, 第一个字符是什么就会读取什么
在这里插入图片描述
此例中, 输入了"a_b", scanf将第一个字符a赋值给ch1后, 接着读取到的字符是空格, 将其赋值给了ch2

%s:

(1)%s读取时从第一个非空白字符开始, 遇到空白结束

正因如此, scanf函数的%s格式控制符无法读取含有空格的字符串。解决方法:
①使用其他输入函数,如gets()
②使用%[]格式控制符

(2)%s读取时会自动吃掉第一个非空白字符前面的空白
在这里插入图片描述
此例中,输入"_ _ _ hello _ world", 前三个空格被吃掉后, 开始从’h’读取, 遇到’o’后面的空格结束, 因此数组中只有hello

格式控制字符串

(1)格式控制字符串中遇到空白会从缓冲区吃掉0~n个连续空白, 此命令只有在遇到非空白字符时才会结束
在这里插入图片描述
此例中, 格式控制字符串为"%d_“, 输入"6"后按了enter键, 缓冲区中的数据为"6\n”, 将6赋值给a后, 从缓冲区开始吃空白, 将\n吃掉后没有数据了, 但是没有遇到非空白字符, 此命令继续要求从键盘输入数据, 直至遇到0, 命令结束。

(2)格式控制字符串中遇到非空白字符, 会在缓冲区中主动读取下一个字符, 若两个字符相同, 则继续进行读取操作; 若不相同, 本条scanf语句结束, 未读取的不再进行读取。(这也是网上说格式控制字符串里有什么, 就要输入什么的原因)
在这里插入图片描述
此例中, 格式控制字符串为"%d(),%d", 输入"6(),8", 非空白字符完全一致, 因此a、b都被成功赋值, scanf返回2
在这里插入图片描述
与上例同样的格式控制字符串, 输入"6_8", 空格与’ ( '不一致, 因此本条语句结束, 只有a被成功赋值, b依然为0, scanf返回1

总结

以上便是我所总结的有关scanf函数的运行机制, 目前笔者遇到的任何关于scanf的困惑都可以凭此解决, 希望大家在灵活运用后也可以达到上述程度,从此与scanf函数的疑问说拜拜, 有任何疑问欢迎评论区讨论, 私信也可。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值