wprintf_s

wprintf, fwprintf, swprintf, wprintf_s, fwprintf_s, swprintf_s

在标题中定义
(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>。

参数

-输出文件流写入
缓冲-指向要写入的宽字符字符串的指针
bufsz-最多bufsz-1可以编写宽字符,加上空终止符
格式-指向以空字符结尾的宽字符串的指针,指定如何解释数据。
格式字符串由普通的宽字符(除外%)组成,它们被不变地复制到输出流和转换规范中。每个转换规范具有以下格式:
介绍%人物
(可选)一个或多个修改转换行为的标志:
-:转换的结果在字段内左对齐(默认情况下它是右对齐的)
+:带符号转换的符号总是预设为转换结果的前缀(默认情况下结果前面为减号,仅当它为负值时)
空格:如果签名转换的结果不是以符号字符开头,或者是空的,则空格会预设为结果。如果+标志存在,它将被忽略。
#:执行转换的替代形式。请参阅下表以了解确切的效果,否则行为未定义。
0:对于整数和浮点数转换,前导零用于填充字段而不是空格字符。对于整数,如果明确指定了精度,它将被忽略。对于使用此标志的其他转换会导致未定义的行为。如果-标志存在,它将被忽略。
(可选)整数值或*指定最小字段宽度。如果需要,结果会填充空格字符(默认情况下),右侧对齐时填充空白字符,左侧填充右侧填充。在使用的情况下*,宽度由类型的附加参数指定int。如果参数的值是负数,则结果是-指定的标志和正的字段宽度。(注意:这是最小宽度:该值从不被截断。)
(可选) .后面跟随整数或者*或者既不指定转换的精度。在使用的情况下*,精度由类型的附加参数指定int。如果这个参数的值是负数,它将被忽略。如果既不使用数字也不*使用,则精度取为零。请参阅下表以了解精确度的确切影响。
(可选) 长度修饰符,用于指定参数的大小
转换格式说明符
以下格式说明符可用:
转换
说明符
长度修饰符
%
c
s
d
i
o
x
X
u
f
F
e
E
a
A
(C99)。
g
G
n
p
浮点转换函数将无穷大转换为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在相同的调用中打印由较早修改的字符串。
如果转换规范无效,则行为未定义。
...-指定要打印的数据的参数

返回值

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ß水?'