C参考手册
文件输入/输出 | File input/output
swprintf
Defined in header <wchar.h> |
||
---|---|---|
(1) |
||
int wprintf( const wchar_t *format, ... ); |
(since C95) (until C99) |
|
int wprintf( const wchar_t *restrict format, ... ); |
(since C99) |
|
(2) |
||
int fwprintf( FILE *stream, const wchar_t* format, ... ); |
(since C95) (until C99) |
|
int fwprintf( FILE *restrict stream, const wchar_t *restrict format, ... ); |
(since C99) |
|
(3) |
||
int swprintf( wchar_t *buffer, size_t bufsz, const wchar_t* format, ... ); |
(since C95) (until C99) |
|
int swprintf( wchar_t *restrict buffer, size_t bufsz, const wchar_t *restrict format, ... ); |
(since C99) |
|
int wprintf_s( const wchar_t *restrict format, ...); |
(4) |
(since C11) |
int fwprintf_s( FILE *restrict stream, const wchar_t *restrict format, ...); |
(5) |
(since C11) |
int swprintf_s( wchar_t *restrict buffer, rsize_t bufsz, const wchar_t* restrict format, ...); |
(6) |
(since C11) |
int snwprintf_s( wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...); |
(7) |
(since C11) |
从给定的位置加载数据,将它们转换为宽字符串等值并将结果写入各种接收器。
1)将结果写入stdout
。
2)将结果写入文件流stream
。
3)如果bufsz
大于零,则将结果写入宽字符串buffer
。最bufsz-1
宽字符后面跟着空宽字符。如果bufsz
为零,则不会写入任何内容(并且buffer
可能是空指针),但返回值(将写入的宽字符数)仍然会计算并返回。
4-6)与(1-3)相同,但在运行时检测到以下错误并调用当前安装的约束处理函数:
- 转换说明符
%n
存在于format
- 任何对应的参数
%s
都是空指针 -
format
或者buffer
是空指针 -
bufsz
是零或大于RSIZE_MAX/sizeof(wchar_t)
- 编码错误出现在任何字符串和字符转换说明符中
- (仅限于
swprintf_s
)要写入的宽字符数(包括null)将超过bufsz
。
7)与(6)相同,只是它会截断结果以适应s所指向的数组。由于所有的边界检查功能,wprintf_s
,wfprintf_s
,和wsprintf_s
仅保证可供如果__STDC_LIB_EXT1__
由实现所定义,并且如果用户定义__STDC_WANT_LIB_EXT1__
的整数常数1
,包括之前<stdio.h>
。
参数
流 |
- |
输入文件流从中读取 |
||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
缓冲 |
- |
指向以null结尾的字符串读取的指针 |
||||||||||
格式 |
- |
指向以空字符结尾的字符串的指针,指定如何读取输入。 |
||||||||||
格式字符串由。 | ||||||||||||
非空白多字节字符除外%:格式字符串中的每个这样的字符只消耗输入流中的一个完全相同的字符,或者如果流中的下一个字符不相等,则会导致函数失败。 | ||||||||||||
空白字符:格式字符串中的任何单个空白字符都会消耗输入中所有可用的连续空白字符(如同通过调用isspace循环来确定)。请注意,有没有什么区别"\n"," ","\t\t"在格式字符串或其他空白。 | ||||||||||||
转换规格。每个转换规范具有以下格式: | ||||||||||||
介绍%人物 | ||||||||||||
(可选)分配抑制字符*。如果存在此选项,则函数不会将转换结果分配给任何接收参数。 | ||||||||||||
(可选)指定最大字段宽度的整数数字(大于零),即该函数在执行由当前转换规范指定的转换时允许使用的最大字符数。请注意,如果未提供宽度,%s和%[可能会导致缓冲区溢出。 | ||||||||||||
(可选) 长度修饰符,用于指定接收参数的大小,即实际的目标类型。这会影响转换精度和溢出规则。每种转换类型的默认目标类型都不相同(请参阅下表)。 | ||||||||||||
转换格式说明符 | ||||||||||||
以下格式说明符可用: | ||||||||||||
转换 |
说明 |
参数类型 |
||||||||||
说明符 | ||||||||||||
长度修饰符 |
hh |
h |
(没有) |
l |
ll |
j |
z |
t |
L |
|||
(C99)。 |
(C99)。 |
(C99)。 |
(C99)。 |
(C99)。 |
||||||||
% |
匹配文字 % |
N / A |
N / A |
N / A |
N / A |
N / A |
N / A |
N / A |
N / A |
N / A |
||
c |
匹配一个字符或一系列字符 |
N / A |
N / A |
char* |
wchar_t* |
N / A |
N / A |
N / A |
N / A |
N / A |
||
如果使用宽度说明符,则完全匹配宽度字符(参数必须是指向具有足够空间的数组的指针)。与%s和%[不同,不会将空字符追加到数组。 | ||||||||||||
s |
匹配一系列非空白字符(一个字符串) |
|||||||||||
如果使用宽度说明符,则匹配宽度或直到第一个空白字符(以先出现者为准)。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。 | ||||||||||||
[组] |
匹配一组字符中的非空字符序列。 |
|||||||||||
如果该集合的第一个字符是^,则不匹配该集合中的所有字符。如果集合以该字符开头]或者^]该]字符也包含在集合中。它是实现定义的-,即扫描集中非初始位置的字符是否可以指示范围,如in [0-9]。如果使用宽度说明符,则只匹配宽度。除了匹配的字符外,总是存储一个空字符(所以参数数组必须至少有宽度+ 1个字符的空间)。 | ||||||||||||
d |
匹配一个十进制整数。 |
signed char* 要么 unsigned char* |
signed short* 要么 unsigned short* |
signed int* 要么 unsigned int* |
signed long* 要么 unsigned long* |
signed long long*要么 unsigned long long* |
intmax_t*要么 uintmax_t* |
size_t* |
ptrdiff_t* |
N / A |
||
数的格式是相同的通过按预期strtol()与值10的base参数。 | ||||||||||||
i |
匹配一个整数。 |
|||||||||||
数的格式是相同的通过按预期strtol()与值0的base参数(基部由解析的第一字符确定)。 | ||||||||||||
u |
匹配一个无符号的十进制整数。 |
|||||||||||
数的格式是相同的通过按预期strtoul()与值10的base参数。 | ||||||||||||
o |
匹配一个无符号的八进制整数。 |
|||||||||||
数的格式是相同的通过按预期strtoul()与值8的base参数。 | ||||||||||||
x, X |
匹配一个无符号的十六进制整数。 |
|||||||||||
数的格式是相同的通过按预期strtoul()与值16的base参数。 | ||||||||||||
n |
返回到目前为止读取的字符数。 |
|||||||||||
没有输入被消耗。不增加分配计数。如果说明符具有定义的分配抑制运算符,则行为未定义。 | ||||||||||||
a,A(C99) , |
匹配一个浮点数。 |
N / A |
N / A |
float* |
double* |
N / A |
N / A |
N / A |
N / A |
long double* |
||
e,,E |
数字的格式与预期的相同strtof()。 |
|||||||||||
fF |
||||||||||||
gG |
||||||||||||
p |
匹配定义指针的实现定义的字符序列。 |
N / A |
N / A |
void** |
N / A |
N / A |
N / A |
N / A |
N / A |
N / A |
||
printf函数族应该使用%p格式说明符产生相同的序列。 | ||||||||||||
对于每个转换说明符以外的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。 | ||||||||||||
... |
- |
接收参数 |
- 介绍
%
人物 - (可选)一个或多个修改转换行为的标志:
-
-
:转换的结果在字段内左对齐(默认情况下它是右对齐的) -
+
:带符号转换的符号总是预设为转换结果的前缀(默认情况下结果前面为减号,仅当它为负值时) -
空格:如果签名转换的结果不是以符号字符开头,或者是空的,则空格会预设为结果。如果
+
存在标志,则忽略它。 -
#
:执行转换的替代形式。请参阅下表以了解确切的效果,否则行为未定义。 -
0
:对于整数和浮点数转换,前导零用于填充字段而不是空格字符。对于整数,如果明确指定了精度,它将被忽略。对于使用此标志的其他转换会导致未定义的行为。如果-
存在标志,则忽略它。
-
- (可选)整数值或
*
指定最小字段宽度。如果需要,结果会填充空格字符(默认情况下),右侧对齐时填充空白字符,左侧填充右侧填充。在使用的情况下*
,宽度由类型的附加参数指定int
。如果参数的值是负数,则结果是-
指定的标志和正的字段宽度。(注意:这是最小宽度:该值从不被截断。)- (可选)
.
后面跟随整数或者*
或者既不指定转换的精度。在使用的情况下*
,精度由类型的附加参数指定int
。如果这个参数的值是负数,它将被忽略。如果既不使用数字也不*
使用,则精度取为零。请参阅下表以了解精确度的确切影响。 - (可选)长度修饰符,用于指定参数的大小
- 转换格式说明符
- (可选)
以下格式说明符可用:
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
写入单个字符。参数首先被转换wchar_t
为仿佛通过调用btowc
。如果使用l修饰符,wint_t
则首先将参数转换为wchar_t
。
N/A N/A int
wint_t
N / AN / AN / AN / AN / A s
写入字符串参数必须是一个指向字符数组初始元素的指针,该字符数组包含一个多字节字符序列,从初始移位状态开始,转换为宽字符数组,如同通过调用mbrtowc
具有零初始化转换状态。Precision指定要写入的最大宽字符数。如果未指定Precision,则将每个宽字符写入并不包括第一个空终止符。如果使用l说明符,参数必须是指向数组的初始元素的指针wchar_t
。
N/A N/A char*
wchar_t*
N/A N/A N/A N/A N/A d
i
将有符号的整数转换为十进制表示形式-dddd。 精度指定出现的最小位数。默认的精度是1
。
如果转换后的值和精度都是0
没有字符的转换结果。
signed char
short
int
long
long long
intmax_t
signed size_t
ptrdiff_t
N / A o
将无符号整数转换为八进制表示oooo。 精度指定出现的最小位数。默认的精度是1
。如果转换后的值和精度都是0
没有字符的转换结果。在替代实现中,如果需要,可以增加精度以写入一个前导零。在这种情况下,如果转换值和精度都是0
,0
写入单个。
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
uintmax_t
size_t
unsigned version of ptrdiff_t
N/A x
X
将无符号整数转换为十六进制表示hhhh。使用x
转换字母abcdef
。
使用X
转换字母ABCDEF
。
精度指定出现的最小位数。默认的精度是1
。如果转换后的值和精度都是0
没有字符的转换结果。在替代实现中, 0x
或者0X
如果转换后的值不为零,则将其作为结果的前缀。
N / A u
将无符号整数转换为十进制表示形式dddd。 精度指定出现的最小位数。默认的精度是1
。如果转换后的值和精度都是0
没有字符的转换结果。
N/A f
F
将浮点数转换为样式-ddd.ddd中的小数表示法。 精度指定小数点后面出现的最小位数。默认的精度是6
。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
N/A N/A double
`double` (C99)
N/A N/A N/A N/A long double
`e`
E
将浮点数转换为十进制指数符号。对于e
转换样式,使用-d.ddd e
±dd。
对于E
转换样式,使用-d.ddd E
±dd。
指数至少包含两位数字,只有在必要时才使用更多数字。如果值是0
,指数也是0
。精度指定小数点后面出现的最小位数。默认的精度是6
。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
N/A N/A N/A N/A N/A N/A a
A
(C99).
将浮点数转换为十六进制指数表示法。对于a
转换样式- 使用0x
h.hhh p
±d。
对于A
转换样式- 使用0X
h.hhh P
±d。
0
如果参数不是标准化的浮点值,则第一个十六进制数字是。如果值是0
,指数也是0
。精度指定小数点后面出现的最小位数。默认精度足以精确表示值。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
N/A N/A N/A N/A N/A N/A g
G
根据值和精度 将浮点数转换为十进制或十进制指数符号。对于风格转换的转换与风格或将被执行。gef
对于G
风格转换的转换与风格E
或F
将被执行。
让P
等于精度如果非零,6
如果没有指定精度,或者1
如果精度是0
。然后,如果具有样式的转换E
将具有以下指数X
:
- 如果P> X≥-4,转换是用式
f
或F
和精度P - 1 - X。 - 否则,转换采用样式
e
或E
精度P - 1。
除非请求替代表示,否则尾随零将被删除,如果没有剩余小数部分,小数点字符也会被删除。对于无穷大和非数字转换风格,请参阅注释。
不适用/不适用/不适用/不适用/ n
返回此函数迄今为止写入的字符数。结果写入参数指向的值。规范可能不包含任何标志,字段宽度或精度。
signed char*
short*
int*
long*
long long*
intmax_t*
signed size_t*
ptrdiff_t*
N / A p
写入一个实现定义的字符序列来定义一个指针。不适用不适用不适用不适用不适用不适用 void*
浮点转换函数将无穷大转换为inf
或infinity
。使用哪一个是实现定义的。
非数字转换为nan
或。使用哪一个是实现定义的。nan(char_sequence)
该转换F
,E
,G
,A
输出INF
,INFINITY
,NAN
来代替。
即使%c
需要int
参数,通过char
调用可变参数函数时发生的整数提升也是安全的。
对于固定宽度的字符类型(正确的转换规格int8_t
<inttypes.h>还(虽然,等等)都在头定义PRIdMAX
,PRIuMAX
等是同义词%jd
,%ju
等)。
内存写入转换说明符%n
是安全漏洞的常见目标,其中格式字符串取决于用户输入,并且不受边界检查printf_s
函数族的支持。
每个转换说明符的操作之后都有一个序列点; 这允许将多个%n
结果存储在相同的变量中,或者作为边缘情况,%n
在同一个调用中打印由较早修改的字符串。
如果转换规范无效,则行为未定义。
... - arguments specifying data to print
返回值
1,2)如果发生错误,则成功写入宽字符数或写入负值。
3)如果编码错误发生或者如果要生成的字符数等于或大于size
(包括当size
为零时),则写入的宽字符的数目(不包括终止空宽字符)如果成功或负值。
4,5)如果发生错误,则成功写入宽字符数或写入负值。
6)写入的宽字符数(不包括终止空值)buffer
。返回编码错误和溢出时的负值。对所有其他错误返回零。
7)将已经写入宽字符(不包括终止空)数量buffer
已经bufsz
如果发生错误,已经足够大时,或为负值。(也就是说,只有当回报是非负的且小于时,写才能成功并且完成bufsz
)
注意
虽然窄字符串提供snprintf
了可以确定所需的输出缓冲区大小的可能性,但对于宽字符串没有等效(直到C11的snwprintf_s),并且为了确定缓冲区大小,程序可能需要调用swprintf
,检查结果值,并重新分配一个更大的缓冲区,再次尝试直到成功。
snwprintf_s
不同swprintf_s
,将截断结果以适应指向的数组buffer
,即使截断被大多数边界检查函数视为错误。
例
#include <locale.h>
#include <wchar.h>
int main(void)
{
char narrow_str[] = "z\u00df\u6c34\U0001f34c";
// or "zß水?"
// or "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9f\x8d\x8c";
wchar_t warr[29]; // the expected string is 28 characters plus 1 null terminator
setlocale(LC_ALL, "en_US.utf8");
swprintf(warr, sizeof warr/sizeof *warr,
L"Converted from UTF-8: '%s'", narrow_str);
wprintf(L"%ls\n", warr);
}
输出:
Converted from UTF-8: 'zß水?'
参考
- C11标准(ISO / IEC 9899:2011):
- 7.29.2.1 fwprintf函数(p:403-410)
- 7.29.2.3 swprintf函数(p:416)
- 7.29.2.11 wprintf函数(p:421)
- K.3.9.1.1 fwprintf_s函数(p:628)
- K.3.9.1.4 swprintf_s函数(p:630-631)
- K.3.9.1.13 wprintf_s函数(p:637-638)
- C99标准(ISO / IEC 9899:1999):
- 7.24.2.1 fwprintf函数(p:349-356)
- 7.24.2.3 swprintf函数(p:362)
- 7.24.2.11 wprintf函数(p:366)