跳转到内容

scanf, fscanf, sscanf :扫描并格式化输入

#include <stdio.h>
int scanf(const char *format [, arg, ...]);
int fscanf(FILE *fd, const char *format [, arg, ...]);
int sscanf(const char *str, const char *format [, arg, ...]);
```### Description
scanf 每次一个字符地从标准输入扫描一系列输入字段。每个字段根据传递给 scanf 的格式字符串中 *format 处的格式说明符进行解释。scanf 将每个字段解释后的输入存储在作为 format 后的相应参数传递给它的地址中。您必须提供与输入字段数量相同的格式说明符和地址参数。
对于给定的格式说明符,必须有足够的地址参数;否则,结果是不可预测的,并且很可能是灾难性的。多余的地址参数将被直接忽略。
如果输入偏离了预期的模式,scanf 通常会产生意外结果。由于 gets 或 fgets 后跟 sscanf 的组合是安全且简单的,因此这是确保程序在行尾与输入同步的首选方法。
fscanf 和 sscanf 与 scanf 完全相同,只是输入源不同:fscanf 从文件读取,而 sscanf 从字符串读取。
*format 处的字符串是由零个或多个指令组成的字符序列。指令由一个或多个空白字符、非空白字符和格式规范组成。
空白字符是空格 ( )、制表符 (\t) 或换行符 (\n)。当 scanf 在格式字符串中遇到空白字符时,它将读取(但不存储)所有连续的空白字符,直到输入中的下一个非空白字符。
非空白字符是除百分号 (%) 之外的所有其他 ASCII 字符。当 scanf 在格式字符串中遇到非空白字符时,它将读取但不存储匹配的非空白字符。
格式规范告诉 scanf 读取输入字段中的字符并将其转换为特定类型的值,然后将其存储在由地址参数指定的位置。
尾随空白将保持未读状态,除非在格式字符串中显式匹配。格式说明符必须以百分号 (%) 开头,并具有以下形式:
%[*][width][size]type
每个格式规范以百分号字符 (%) 开头。其他字段为:* 一个可选标记;如果存在,它将抑制对当前输入字段的解释和赋值。width 一个可选的最大字段宽度:一个十进制整数,用于控制在转换当前输入字段之前将读取的最大字符数。如果输入字段的字符数少于 width,scanf 将读取该字段中的所有字符,然后继续处理下一个字段及其格式规范。如果在读取 width 个字符之前出现空白或不可转换的字符,则读取直到该字符为止的字符,并进行转换和存储。然后 scanf 继续处理下一个格式规范。size h、l 和 L 是可选的大小字符,它们覆盖 scanf 解释相应参数数据类型的默认方式。修饰符 类型 h d, i, o, u, x 将输入转换为 short,存储在 short 对象中 h D, I, O, U, X 无效 e, f, c, s, n, p l d, i, o, u, x 将输入转换为 long,存储在 long 对象中 l e, f, g 将输入转换为 double,存储在 double 对象中 l D, I, O, U, X 无效 c, s, n, p L d, i, o, u, x 转换为 long double,存储在 long double 中 L 所有其他 无效 type 一个字符,用于指定 scanf 执行哪种转换。以下是转换字符表:% 不进行转换;存储百分号字符 (%)。c 扫描一个字符。对应的 arg:(char *arg)。s 将字符串读入提供的数组中。对应的 arg:(char arg[])。[pattern] 将非空字符串读入从 arg 开始的内存中。该区域必须足够大以接受该序列以及将自动添加的终止空字符。(pattern 在本表后面的段落中讨论)。对应的 arg:(char *arg)。d 将十进制整数读入对应的 arg:(int *arg)。D 将十进制整数读入对应的 arg:(long *arg)。o 将八进制整数读入对应的 arg:(int *arg)。O 将八进制整数读入对应的 arg:(long *arg)。u 将无符号十进制整数读入对应的 arg:(unsigned int *arg)。U 将无符号十进制整数读入对应的 arg:(unsigned long *arg)。x,X 将十六进制整数读入对应的 arg:(int *arg)。e, f, g 将浮点数读入对应的 arg:(float *arg)。E, F, G 将浮点数读入对应的 arg:(double *arg)。i 将十进制、八进制或十六进制整数读入对应的 arg:(int *arg)。I 将十进制、八进制或十六进制整数读入对应的 arg:(long *arg)。n 将读取的字符数存储在对应的 arg:(int *arg) 中。p 存储扫描到的指针。ANSI C 将细节留给各个实现;此实现将 %p 与 %U 完全相同地处理。对应的 arg:(void **arg)。
可以用方括号括起来的字符模式代替 s 类型字符。pattern 是一组字符,它定义了构成 scanf 输入字段的可能字符的搜索集。如果方括号中的第一个字符是脱字符 (^),则搜索集将被反转,以包括方括号之间除指定字符之外的所有 ASCII 字符。还有一个范围功能,您可以将其用作快捷方式。%[0-9] 匹配所有十进制数字。连字符不能是集合中的第一个或最后一个字符。连字符前面的字符在词法上必须小于连字符后面的字符。以下是一些模式示例:%[abcd] 匹配仅包含 a、b、c 和 d 的字符串。%[^abcd] 匹配包含除 a、b、c 或 d 之外的任何字符的字符串 %[A-DW-Z] 匹配包含 A、B、C、D、W、X、Y、Z 的字符串 %[z-a] 匹配字符 z、- 和 a
浮点数(对于字段类型 e、f、g、E、F、G)必须符合以下一般形式:[+/-] ddddd[.]ddd [E|e[+|-]ddd] 其中方括号中的对象是可选的,ddd 表示十进制、八进制或十六进制数字。### Returns
scanf 返回成功扫描、转换和存储的输入字段的数量;返回值不包括已扫描但未存储的字段。
如果 scanf 尝试在文件末尾读取,则返回值为 EOF。
如果没有存储任何字段,则返回值为 0。
scanf 可能会在到达正常字段结束字符之前停止扫描特定字段,或者可能完全终止。
在以下任何情况下,scanf 将停止扫描和存储当前字段,并移动到下一个输入字段(如果有):在格式规范中 % 之后出现赋值抑制字符 (*);扫描当前输入字段但不存储它。已读取 width 个字符(width 是宽度规范,一个正十进制整数)。读取的下一个字符无法在当前格式下转换(例如,当格式为十进制时读取了 Z)。输入字段中的下一个字符未出现在搜索集中(或出现在反转搜索集中)。
当 scanf 因上述原因之一停止扫描当前输入字段时,下一个字符被视为未读,并用作以下输入字段的第一个字符,或作为对输入的后续读取操作中的第一个字符。
scanf 将在以下情况下终止:输入字段中的下一个字符与格式字符串中相应的非空白字符冲突。输入字段中的下一个字符是 EOF。格式字符串已耗尽。
当格式字符串包含不属于格式规范的字符序列时,输入中必须出现相同的字符序列;scanf 将扫描但不存储匹配的字符。如果发生冲突,第一个冲突字符将保留在输入中,就像它从未被读取过一样。
---
**权威来源**: BUSMASTER DITA help source `scanf.dita`, compiled into `BUSMASTER.CHM` with the application.