©
本文档使用
php.cn手册 发布
Defined in header <stdio.h> | ||
---|---|---|
int vscanf( const char *restrict format, va_list vlist ); | (1) | (since C99) |
int vfscanf( FILE *restrict stream, const char *restrict format, va_list vlist ); | (2) | (since C99) |
int vsscanf( const char *restrict buffer, const char *restrict format, va_list vlist ); | (3) | (since C99) |
int vscanf_s(const char *restrict format, va_list vlist); | (4) | (since C11) |
int vfscanf_s( FILE *restrict stream, const char *restrict format, va_list vlist); | (5) | (since C11) |
int vsscanf_s( const char *restrict buffer, const char *restrict format, va_list vlist); | (6) | (since C11) |
从各种来源读取数据,根据其解释并将format
结果存储到由其定义的位置vlist
。
1)从中读取数据 stdin
2)从文件流中读取数据 stream
3)从以空字符结尾的字符串读取数据buffer
。到达字符串的末尾等同于达到文件结束条件fscanf
4-6)与(1-3)相同,不同之处在于%c
,%s
和%[
转换说明符每个都需要两个参数(通常的指针和rsize_t
表示接收数组大小的类型值,当使用%c读取时可能为1成一个字符),除了在运行时检测到以下错误并调用当前安装的约束处理函数:
指针类型的任何参数都是空指针
format
,stream
或者buffer
是空指针
%c,%s或%[,加上终止空字符,将会超过为每个转换说明符提供的第二个(rsize_t)参数所写的字符数
可选地,还有任何其他可检测到的错误,例如未知的转换说明符
由于所有的边界检查功能,vscanf_s
,vfscanf_s
,和vsscanf_s
仅保证可供如果__STDC_LIB_EXT1__
由实现所定义,并且如果用户定义__STDC_WANT_LIB_EXT1__
的整数常数1
,包括之前<stdio.h>
。
流 | - | 输入文件流从中读取 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
缓冲 | - | 指向以null结尾的字符串读取的指针 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
格式 | - | 指向以空字符结尾的字符串的指针,指定如何读取输入。格式字符串由。非空白多字节字符除%以外:格式字符串中的每个这样的字符只会从输入流中消耗一个完全相同的字符,或者如果流中的下一个字符不相等,则会导致函数失败。空格字符:格式字符串中的任何单个空白字符都会消耗输入中的所有可用连续空格字符(如同通过调用循环中的isspace一样来确定)。请注意,格式字符串中的“\ n”,“”,“\ t \ t”或其他空格没有区别。转换规格。每个转换规范具有以下格式:介绍%字符(可选)分配抑制字符*。如果存在此选项,则函数不会将转换结果分配给任何接收参数。(可选)指定最大字段宽度的整数数字(大于零),即该函数在执行当前转换规范指定的转换时允许使用的最大字符数。请注意,如果未提供宽度,%s和%[可能会导致缓冲区溢出。(可选)长度修饰符,用于指定接收参数的大小,即实际的目标类型。这会影响转换精度和溢出规则。每种转换类型的默认目标类型都不相同(请参阅下表)。转换格式说明符以下格式说明符可用:转换说明符说明参数类型长度修饰符hh(C99)。h(无)ll(C99)。j(C99)。z(C99)。t(C99)。L%匹配字面值%N / AN / AN / AN / AN / AN / AN / AN / AN / c与字符或字符序列匹配如果使用宽度说明符,则匹配完全宽度字符(参数必须是指向具有足够空间的阵列的指针)。与%s和%[不同,不会将空字符追加到数组。N / AN / A char * wchar_t * N / AN / AN / AN / AN / A与非空白字符序列(字符串)匹配如果使用宽度说明符,则匹配宽度或直到第一个空白字符,以先出现者为准。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。集匹配字符集中的非空字符序列。如果该集合的第一个字符是^,则不匹配该集合中的所有字符。如果该集合以]或^]开头,则该字符也包含在集合中。它是实现定义的,字符 - 在扫描集中的非初始位置可以指示一个范围,如0-9。如果使用宽度说明符,则只匹配宽度。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。d匹配一个十进制整数。数字的格式与strtol()预期的相同,基本参数的值为10。有符号字符*或无符号字符*有符号短符号*或无符号短符号*有符号整数*或无符号整数*有符号长符号*无符号长符号*长符号*长符号或无符号长符号* intmax_t *或uintmax_t * size_t * ptrdiff_t * N / A i匹配一个整数。数字的格式与strtol()所预期的相同,基本参数的值为0(基数由解析的第一个字符决定)。你匹配一个无符号的十进制整数。数字的格式与strtoul()的预期相同,基本参数的值为10。o匹配一个无符号的八进制整数。数字的格式与strtoul()所预期的基本参数的值为8相同。x,X匹配一个无符号的十六进制整数。数字的格式与strtoul()预期的基本参数的值为16相同。n返回到目前为止读取的字符数。没有输入被消耗。不增加分配计数。如果说明符具有定义的分配抑制运算符,则行为是未定义的。a,A(C99)e,E f,F g,G匹配一个浮点数。数字的格式与strtof()的预期相同。N / AN / A float * double * N / AN / AN / AN / long long double * p匹配定义指针的实现定义字符序列。printf系列函数应该使用%p格式说明符产生相同的序列。N / AN / A void ** N / AN / AN / AN / AN / AN / A对于除n以外的每个转换说明符,输入字符的最长序列不超过任何指定的字段宽度,并且或者正是转换说明符所期望的或者是期望的序列的前缀,是从流中消耗的东西。在消耗序列之后的第一个字符(如果有的话)仍然未读。如果消耗的序列长度为零或消费的序列无法如上所述进行转换,则会发生匹配失败,除非文件结束,编码错误或读取错误阻止来自流的输入,在这种情况下,它是输入失败。在尝试解析输入之前,除[,c和n之外的所有转换说明符都会消耗并放弃所有前导空白字符(通过调用isspace确定)。这些消耗的字符不会计入指定的最大字段宽度。转换说明符lc,ls和l [执行多字节到宽字符转换,就好像通过调用mbrtowc(),并在转换第一个字符之前将mbstate_t对象初始化为零。转换说明符s和[除了匹配的字符外,总是存储空终止符。目标数组的大小必须至少比指定的字段宽度大1。使用%s或%[,不指定目标数组大小,与get一样不安全。固定宽度整数类型(int8_t等)的正确转换规范在标头<inttypes.h>中定义(尽管SCNdMAX,SCNuMAX等与%jd,%ju等同义)。每个转换说明符的操作之后都有一个序列点; 这允许将多个字段存储在相同的“汇”变量中。当解析一个不带数字的指数结束的不完整浮点值时,例如用转换说明符%f解析“100er”时,会消耗序列“100e”(可能有效的浮点数的最长前缀) ,导致匹配错误(消耗的序列不能转换为浮点数),并保留“r”。现有的实现不遵循这个规则,并回滚到只消耗“100”,留下“呃”,例如glibc错误1765。导致匹配错误(消耗的序列不能转换为浮点数),并保留“r”。现有的实现不遵循这个规则,并回滚到只消耗“100”,留下“呃”,例如glibc错误1765。导致匹配错误(消耗的序列不能转换为浮点数),并保留“r”。现有的实现不遵循这个规则,并回滚到只消耗“100”,留下“呃”,例如glibc错误1765。 | 转换说明符 | 说明 | 参数类型 | 长度修饰符 | hh(C99)。 | H | (没有) | 升 | (C99)。 | j(C99)。 | 来自(C99)。 | t(C99)。 | 该 | % | 匹配文字% | N / A | N / A | N / A | N / A | N / A | N / A | N / A | N / A | N / A | C | 匹配一个字符或一系列字符如果使用了宽度说明符,则完全匹配宽度字符(参数必须是指向具有足够空间的数组的指针)。与%s和%[不同,不会将空字符追加到数组。 | N / A | N / A | 字符* | wchar_t的* | N / A | N / A | N / A | N / A | N / A | 小号 | 匹配非空白字符序列(字符串)如果使用宽度说明符,则匹配宽度或直到第一个空白字符(以先出现者为准)。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。 | 组 | matches a non-empty sequence of character from set of characters. If the first character of the set is ^, then all characters not in the set are matched. If the set begins with ] or ^] then the ] character is also included into the set. It is implementation-defined whether the character - in the non-initial position in the scanset may be indicating a range, as in 0-9. If width specifier is used, matches only up to width. Always stores a null character in addition to the characters matched (so the argument array must have room for at least width+1 characters). | d | matches a decimal integer. The format of the number is the same as expected by strtol() with the value 10 for the base argument. | signed char* or unsigned char* | signed short* or unsigned short* | signed int* or unsigned int* | signed long* or unsigned long* | signed long long* or unsigned long long* | intmax_t* or uintmax_t* | size_t* | ptrdiff_t* | N/A | i | matches an integer. The format of the number is the same as expected by strtol() with the value 0 for the base argument (base is determined by the first characters parsed). | u | matches an unsigned decimal integer. The format of the number is the same as expected by strtoul() with the value 10 for the base argument. | o | matches an unsigned octal integer. The format of the number is the same as expected by strtoul() with the value 8 for the base argument. | x, X | matches an unsigned hexadecimal integer. The format of the number is the same as expected by strtoul() with the value 16 for the base argument. | n | returns the number of characters read so far. No input is consumed. Does not increment the assignment count. If the specifier has assignment-suppressing operator defined, the behavior is undefined. | a,A(C99)e,E f,F g,G | 匹配一个浮点数。数字的格式与strtof()的预期相同。 | N / A | N / A | 浮动* | 双* | N / A | N / A | N / A | N / A | 长双* | p | 匹配定义指针的实现定义的字符序列。printf系列函数应该使用%p格式说明符产生相同的序列。 | N / A | N / A | 无效** | N / A | N / A | N / A | N / A | N / A | N / A |
转换说明符 | 说明 | 参数类型 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
长度修饰符 | hh(C99)。 | H | (没有) | 升 | (C99)。 | j(C99)。 | 来自(C99)。 | t(C99)。 | 该 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
% | 匹配文字% | N / A | N / A | N / A | N / A | N / A | N / A | N / A | N / A | N / A | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
C | 匹配一个字符或一系列字符如果使用了宽度说明符,则完全匹配宽度字符(参数必须是指向具有足够空间的数组的指针)。与%s和%[不同,不会将空字符追加到数组。 | N / A | N / A | 字符* | wchar_t的* | N / A | N / A | N / A | N / A | N / A | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
小号 | 匹配非空白字符序列(字符串)如果使用宽度说明符,则匹配宽度或直到第一个空白字符(以先出现者为准)。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
组 | 匹配一组字符中的非空字符序列。如果该集合的第一个字符是^,则不匹配该集合中的所有字符。如果该集合以]或^]开头,则该字符也包含在集合中。它是实现定义的,字符 - 在扫描集中的非初始位置可以指示范围,如0-9。如果使用宽度说明符,则只匹配宽度。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
d | 匹配一个十进制整数。数字的格式与strtol()所预期的相同,基本参数的值为10。 | signed char *或unsigned char * | 签署短*或无符号短* | 有符号int *或unsigned int * | 签署长*或无符号长* | 签署长长*或无符号长长* | intmax_t *或uintmax_t * | 为size_t * | ptrdiff_t的* | N / A | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
一世 | 匹配一个整数。数字的格式与strtol()所期望的相同,基本参数的值为0(基数由解析的第一个字符决定)。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
在 | 匹配一个无符号的十进制整数。数字的格式与strtoul()的预期相同,基本参数的值为10。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
该 | 匹配一个无符号的八进制整数。数字的格式与strtoul()的预期相同,基本参数的值为8。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x,X | 匹配一个无符号的十六进制整数。数字的格式与strtoul()预期的基本参数的值为16相同。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ñ | 返回迄今阅读的字符数。没有输入被消耗。不增加分配计数。如果说明符具有定义的分配抑制运算符,则行为是未定义的。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a,A(C99)e,E f,F g,G | 匹配一个浮点数。数字的格式与strtof()的预期相同。 | N / A | N / A | 浮动* | 双* | N / A | N / A | N / A | N / A | 长双* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
p | 匹配定义指针的实现定义的字符序列。printf系列函数应该使用%p格式说明符产生相同的序列。 | N / A | N / A | 无效** | N / A | N / A | N / A | N / A | N / A | N / A | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VLIST | - | 包含接收参数的变量参数列表 |
非空白多字节字符除外%
:格式字符串中的每个这样的字符只消耗输入流中的一个完全相同的字符,或者如果流中的下一个字符不相等,则会导致函数失败。
空白字符:格式字符串中的任何单个空白字符都会消耗输入中所有可用的连续空白字符(如同通过调用isspace
循环来确定)。请注意,有没有什么区别"\n"
," "
,"\t\t"
在格式字符串或其他空白。
转换规格。每个转换规范具有以下格式:
介绍%
人物
(可选)分配抑制字符*
。如果存在此选项,则函数不会将转换结果分配给任何接收参数。
(可选)指定最大字段宽度的整数数字(大于零),即该函数在执行由当前转换规范指定的转换时允许使用的最大字符数。请注意,如果未提供宽度,%s和%[可能会导致缓冲区溢出。
(可选)长度修饰符,用于指定接收参数的大小,即实际的目标类型。这会影响转换精度和溢出规则。每种转换类型的默认目标类型都不相同(请参阅下表)。
转换格式说明符
以下格式说明符可用:
Conversion
说明符说明参数类型长度修饰符 hh
(C99)。
h
(none) l
ll
(C99).
j
(C99).
z
(C99).
t
(C99).
L
%
匹配字面%
N / AN / AN / AN / AN / AN / AN / AN / AN / A c
一个匹配字符或序列字符如果使用宽度说明,完全匹配宽度的字符(参数必须是一个指针数组有足够的空间)。与%s和%[不同,不会将空字符追加到数组。
N/A N/A char*
wchar_t*
N / AN / AN / AN / AN / A s
匹配非空白字符序列(字符串)如果使用宽度说明符,则匹配宽度或直到第一个空白字符,以先出现者为准。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。
`[`set`]` matches a non-empty sequence of character from set of characters. If the first character of the set is `^`, then all characters not in the set are matched. If the set begins with `]` or `^]` then the `]` character is also included into the set. It is implementation-defined whether the character `-` in the non-initial position in the scanset may be indicating a range, as in `[0-9]`. If width specifier is used, matches only up to _width_. Always stores a null character in addition to the characters matched (so the argument array must have room for at least _width+1_ characters).
`d` matches a **decimal integer**. The format of the number is the same as expected by [`strtol()`](../string/byte/strtol) with the value `10` for the `base` argument.
`signed char*` or `unsigned char*`
`signed short*` or `unsigned short*`
`signed int*` or `unsigned int*`
`signed long*` or `unsigned long*`
`signed long long*` or `unsigned long long*`
[`intmax_t`](../types/integer)`*` or [`uintmax_t`](../types/integer)`*`
size_t*
ptrdiff_t*
N / A i
匹配整数。数的格式是相同的通过按预期strtol()
与值0
的base
参数(基部由解析的第一字符确定)。
`u` matches an unsigned **decimal integer**. The format of the number is the same as expected by [`strtoul()`](../string/byte/strtoul) with the value `10` for the `base` argument.
`o` matches an unsigned **octal integer**. The format of the number is the same as expected by [`strtoul()`](../string/byte/strtoul) with the value `8` for the `base` argument.
`x`, `X` matches an unsigned **hexadecimal integer**. The format of the number is the same as expected by [`strtoul()`](../string/byte/strtoul) with the value `16` for the `base` argument.
`n` returns the **number of characters read so far**. No input is consumed. Does not increment the assignment count. If the specifier has assignment-suppressing operator defined, the behavior is undefined.
`a`, `A`(C99)
e
, E
f
, F
g
,G
匹配一个浮点数。数字的格式与预期的相同strtof()
。
N/A N/A float*
double*
N/A N/A N/A N/A long double*
`p` matches implementation defined character sequence defining a **pointer**. `printf` family of functions should produce the same sequence using `%p` format specifier.
N/A N/A void**
n
不适用不适用不适用不适用不适用不适用不适用不适用于任何指定字段宽度的最长输入字符序列的 每个转换说明符,或者正是转换说明符所期望的或者是它期望的顺序是从流中消耗的。在消耗序列之后的第一个字符(如果有的话)仍然未读。如果消耗的序列长度为零或消费的序列不能如上所述进行转换,则会发生匹配失败,除非文件结束,编码错误或读取错误阻止了来自流的输入,在这种情况下,它是输入失败。
在尝试解析输入之前,除了[
,,之外的所有转换说明符都会消耗并放弃所有前导空白字符(如同通过调用一样确定)。这些消耗的字符不会计入指定的最大字段宽度。cnisspace
转换说明符lc
,ls
并l[
执行多字节到宽字符转换,就好像通过在第一个字符转换之前使用初始化为零mbrtowc()
的mbstate_t
对象调用一样。
除了匹配的字符之外,转换说明符s
并[
始终存储空终止符。目标数组的大小必须至少比指定的字段宽度大1。在不指定目标数组大小的情况下,使用%s
或%[
不安全gets
。
对于固定宽度的整数类型(正确的转换规格int8_t
<inttypes.h>还(虽然,等等)都在头定义SCNdMAX
,SCNuMAX
等是同义词%jd
,%ju
等)。
每个转换说明符的操作之后都有一个序列点; 这允许将多个字段存储在相同的“汇”变量中。
在解析指数中不包含数字的不完整浮点值时(例如"100er"
使用转换说明符进行解析),会消耗%f
序列"100e"
(可能有效的浮点数的最长前缀),从而导致匹配错误(消耗的序列不能转换为浮点数),"r"
剩余的。现有的实现不遵循此规则并仅回滚消耗"100"
,只留下"er"
例如glibc错误1765。
vlist - variable argument list containing the receiving arguments
1-3)成功分配的接收参数数目,或者EOF
在分配第一个接收参数前发生读取失败。
4-6)与(1-3)相同,但是EOF
如果存在运行时约束冲突,也会返回。
所有这些函数va_arg
至少调用一次,arg
返回后的值是不确定的。这些函数不会调用va_end
,并且它必须由调用者完成。
#include <stdio.h>#include <stdbool.h>#include <stdarg.h> bool checked_sscanf(int count, const char* buf, const char *fmt, ...){ va_list ap; va_start(ap, fmt); int rc = vsscanf(buf, fmt, ap); va_end(ap); return rc == count;} int main(void){ int n, m; printf("Parsing '1 2'..."); if(checked_sscanf(2, "1 2", "%d %d", &n, &m)) puts("success"); else puts("failure"); printf("Parsing '1 a'..."); if(checked_sscanf(2, "1 a", "%d %d", &n, &m)) puts("success"); else puts("failure");}
输出:
Parsing '1 2'...success Parsing '1 a'...failure