swprintf

wprintf, fwprintf, swprintf, wprintf_s, fwprintf_s, swprintf_s

Defined in header 
(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

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和%[可能会导致缓冲区溢出。
(可选) 长度修饰符,用于指定接收参数的大小,即实际的目标类型。这会影响转换精度和溢出规则。每种转换类型的默认目标类型都不相同(请参阅下表)。
转换格式说明符
以下格式说明符可用:
转换
说明符
长度修饰符
%
c
s
[组]
d
i
u
o
x, X
n
a,A(C99) ,
e,,E
fF
gG
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。
...-接收参数

  • 介绍%人物

以下格式说明符可用:

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转换样式- 使用0xh.hhh p±d

对于A转换样式- 使用0Xh.hhh P±d

0如果参数不是标准化的浮点值,则第一个十六进制数字是。如果值是​0​,指数也是​0​精度指定小数点后面出现的最小位数。默认精度足以精确表示值。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。

N/A N/A N/A N/A N/A N/A g

G根据值和精度浮点数转换为十进制或十进制指数符号。对于风格转换的转换与风格或将被执行。gef

对于G风格转换的转换与风格EF将被执行。

P等于精度如果非零,6如果没有指定精度,或者1如果精度是​0​。然后,如果具有样式的转换E将具有以下指数X

  • 如果P> X≥-4,转换是用式f或F和精度P - 1 - X。

除非请求替代表示,否则尾随零将被删除,如果没有剩余小数部分,小数点字符也会被删除。对于无穷大和非数字转换风格,请参阅注释。

不适用/不适用/不适用/不适用/ n 返回此函数迄今为止写入的字符数。结果写入参数指向的值。规范可能不包含任何标志字段宽度精度

signed char*

short*

int*

long*

long long*

intmax_t*

signed size_t*

ptrdiff_t*

N / A p 写入一个实现定义的字符序列来定义一个指针。不适用不适用不适用不适用不适用不适用 void* 浮点转换函数将无穷大转换为infinfinity。使用哪一个是实现定义的。

非数字转换为nan或。使用哪一个是实现定义的。nan(char_sequence)

该转换FEGA输出INFINFINITYNAN来代替。

即使%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):