c 语言中的 scanf 函数是 stdio.h 标准库提供的格式化输入函数,核心功能是从键盘标准输入缓冲区读取用户输入内容,按照格式控制字符串里的格式符解析数据,并且写入传入的变量内存地址。它属于库函数不是关键字,使用前必须引入 stdio.h 头文件,调用时普通变量一定要搭配取地址符 &,把变量地址交给 scanf,函数才能完成数据写入。scanf 会自动跳过空格、制表符、换行这类空白字符,但是读取单个字符 % c 是例外,不会跳过空白,缓冲区残留回车会被当成有效字符读入,这是初学者最容易踩坑的地方。函数还带有返回值,返回成功赋值的数据项数量,输入类型不匹配时返回值会小于预期,读取失败返回 EOF,可以利用这个返回值做输入合法性校验。
一 基础调用格式
scanf (格式控制字符串,变量地址列表);
格式控制字符串由格式符和普通字符组成,普通字符要求用户输入时必须原样输入匹配,一般不推荐在格式串写多余普通字符,容易增加输入出错概率。
二 常用格式符对照表
| 格式符 | 读取类型 |
|---|---|
| %d | int 十进制整数 |
| %ld | long 长整型 |
| %lld | long long 长长整型 |
| %f | float 单精度浮点数 |
| %lf | double 双精度浮点数 |
| %c | 单个字符 |
| %s | 字符串,遇空白停止 |
| %o | 八进制整数 |
| %x | 十六进制整数 |
三 底层输入缓冲区原理
键盘输入的数据不会直接存入变量,会先存放在操作系统标准输入缓冲区,用户按下回车之后,scanf 才开始解析缓冲区里面的字符。如果本次 scanf 没有读完所有输入字符,剩下字符会继续留在缓冲区,下一次调用 scanf 会优先读取残留内容,很容易造成下一次读取异常,写代码时经常需要根据业务清空缓冲区。
四 核心规则深度说明
第一 取地址规则,int float double 这类普通变量必须写 &,char 数组也就是字符串本身就是首地址,读取 % s 的时候不需要再加 &。
第二 % c 特殊处理,读取单个字符不会跳过空白,解决办法是在 % c 前面加空格,写成 scanf ("% c", &ch); 前置空格用来丢弃缓冲区空白字符。
第三 % s 读取字符串,遇到空格回车就停止,不能读取带空格整行,需要读取整行推荐改用 fgets,同时 % s 没有长度限制,超长输入会缓冲区溢出,可以加上宽度限制例如 %99s。
第四 返回值校验,正式开发判断返回值是否等于预期项数,如果不相等代表用户输入格式错误,需要提示重新输入,不能默认输入一定正确。
第五 多变量连续读取,多个格式符之间默认依靠空白分隔,用户输入数字时可以用空格或者回车隔开。
五 高频误区
误区一 scanf 是 C 语言关键字,错误,它是 stdio.h 里面的库函数。
误区二 读取 double 的时候 scanf 可以写 % f,错误,scanf 读取 double 必须写 % lf,printf 输出 double 才可以用 % f。
误区三 只要调用 scanf 就一定赋值成功,错误,输入类型不匹配的时候变量不会被正确赋值。
误区四 所有变量都要加 &,错误,数组名本身就是地址,不需要额外取地址。
【常见问题】
问题 1 c 语言中的 scanf 函数的用法 为什么调用 scanf 之前要引入 stdio.h
回答 1 c 语言中的 scanf 函数的用法,scanf 的函数声明写在 stdio.h 头文件里面,引入头文件编译器才能识别 scanf,缺少头文件会出现隐式声明警告或者编译报错。
问题 2 c 语言中的 scanf 函数的用法 读取普通 int 变量为什么必须加 &
回答 2 c 语言中的 scanf 函数的用法,scanf 需要拿到变量内存地址才能把读取的数据写进去,& 是取地址符,获取 int 变量内存地址,所以普通 int 变量调用 scanf 必须加上 &。
问题 3 c 语言中的 scanf 函数的用法 % c 读取字符为什么会读到上一次残留回车
回答 3 c 语言中的 scanf 函数的用法,% c 和其他格式符不一样,不会自动跳过空白字符,输入缓冲区里面残留换行符会被当成字符读入,可以在 % c 前面增加空格解决这个问题。
问题 4 c 语言中的 scanf 函数的用法 scanf 返回值有什么作用
回答 4 c 语言中的 scanf 函数的用法,返回值代表成功完成赋值的数据项个数,输入格式不匹配返回值会变小,读取失败返回 EOF,可以依靠返回值判断用户输入是否合法。
【免责申明】
本文是 c 语言中的 scanf 函数的用法相关基础知识讲解,新版部分编译器开启安全检查会提示 scanf 存在溢出风险,推荐使用带长度限制的安全输入函数,不同编译器警告等级和扩展选项存在差异,示例代码仅用于学习演示,实际项目需要增加输入校验,输入异常引发程序错误由开发者自行排查处理。
