vprintf

vprintf, vfprintf, vsprintf, vsnprintf, vprintf_s, vfprintf_s

在标题中定义
-1
INT  vprintf ( const的 字符 *格式, va_list的VLIST );(直到C99)
INT  vprintf ( const的 字符 *限制格式, va_list的VLIST );(自C99以来)
-2
int  vfprintf ( FILE * stream , const  char  * format , va_list vlist );(直到C99)
int  vfprintf ( FILE * restrict stream , const  char  * restrict format ,(自C99以来)
va_list vlist );
-3
int  vsprintf ( char  * buffer , const  char  * format , va_list vlist );(直到C99)
int  vsprintf ( char  * restrict buffer , const  char  * restrict format ,(自C99以来)
va_list vlist );
int  vsnprintf ( char  * restrict buffer , int bufsz ,-4(自C99以来)
const  char  * restrict format , va_list vlist );
int  vprintf_s ( const  char  * restrict format , va_list arg );-5(自C11以来)
int  vfprintf_s ( FILE * restrict stream , const  char  * restrict format ,-6(自C11以来)
va_list arg );
int  vsprintf_s ( char  * restrict buffer , rsize_t bufsz ,-7(自C11以来)
const  char  * restrict format , va_list arg );
int  vsnprintf_s (char  * restrict buffer , rsize_t bufsz ,-8(自C11以来)
const  char  * restrict format , va_list arg );

从定义的位置加载数据vlist,将它们转换为等同字符串并将结果写入各种接收器。

1)将结果写入stdout

2)将结果写入文件流stream

3)将结果写入字符串buffer

4)将结果写入字符串buffer。最多的buf_size字符是写入的。结果字符串将以空字符结尾,除非buf_size为零。如果buf_size为零,则不会写入任何内容,并且buffer可能是空指针,但返回值(将写入的字节数)仍然会计算并返回。

5-8)与(1-4)相同,只是在运行时检测到以下错误并调用当前安装的约束处理函数:

  • 转换说明符%n存在于format

由于所有的边界检查功能,vprintf_s,vfprintf_s,vsprintf_s,和vsnrintf_s仅保证可供如果__STDC_LIB_EXT1__由实现所定义,并且如果用户定义__STDC_WANT_LIB_EXT1__的整数常数1,包括之前<stdio.h>。

参数

转换说明参数类型
说明符
长度修饰符hh
(C99)。
%写文字%。完整的转换规范必须是%%。N / A
c写一个字符。N / A
该论点首先转换为unsigned char。如果使用了l修饰符,则首先将参数转换为字符串,就像通过具有参数的%ls一样wchar_t[2]。
s写入一个字符串N / A
参数必须是指向字符数组的初始元素的指针。Precision指定要写入的最大字节数。如果未指定Precision,则将每个字节写入并不包括第一个空终止符。如果使用了l说明符,则参数必须是指向数组初始元素的指针wchar_t,它将转换为char数组,就像通过调用wcrtomb具有零初始化转换状态一样。
d将有符号整数转换为十进制表示形式[ - ] dddd。signed char
i精度指定出现的最小位数。默认的精度是1。
如果转换后的值和精度都是​0​没有字符的转换结果。
o将无符号整数转换为八进制表示oooo。unsigned char
精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中,如果需要,可以增加精度以写入一个前导零。在这种情况下,如果转换后的值和精度都是​0​,​0​写入单个。
x将无符号整数转换为十六进制表示hhhh。
X使用x转换字母abcdef。
使用X转换字母ABCDEF。
精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。在替代实现中, 0x或者0X如果转换后的值不为零,则将其作为结果的前缀。
u将无符号整数转换为十进制表示形式dddd。
精度指定出现的最小位数。默认的精度是1。如果转换后的值和精度都是​0​没有字符的转换结果。
f将浮点数转换为样式[ - ] ddd.ddd中的十进制表示法。N / A
F精度指定小数点后面出现的最小位数。默认的精度是6。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
e将浮点数转换为十进制指数符号。N / A
E对于e转换样式,使用[ - ] d.ddd e±dd。
对于E转换样式,使用[ - ] d.ddd E±dd。
指数至少包含两位数字,只有在必要时才使用更多数字。如果值是​0​,指数也是​0​。精度指定小数点后面出现的最小位数。默认的精度是6。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
a将浮点数转换为十六进制指数表示法。N / A
A对于a转换样式,使用[ - ] 0xh.hhh p±d。
(C99)。对于A转换样式,使用[ - ] 0Xh.hhh P±d。如果参数不是标准化的浮点值,则
第一个十六进制数字是0。如果值是​0​,指数也是​0​。精度指定小数点后面出现的最小位数。默认精度足以精确表示值。在替代实现中,即使没有数字跟随,小数点字符也会被写入。对于无穷大和非数字转换风格,请参阅注释。
g根据值和精度将浮点数转换为十进制或十进制指数符号。N / A
G对于g风格转换的转换与风格e或f将被执行。
对于G风格转换的转换与风格E或F将被执行。
让P等于精度如果非零,6如果没有指定精度,或者1如果精度是​0​。然后,如果具有样式的转换E将具有以下指数X:
如果P> X≥-4,转换是用式f或F和精度P - 1 - X。
否则,转换采用样式e或E精度P - 1。
除非请求替代表示,否则尾随零将被删除,如果没有剩余小数部分,小数点字符也会被删除。对于无穷大和非数字转换风格,请参阅注释。
n将此调用到目前为止写入的字符数返回给该函数。signed char*
结果写入参数指向的值。规范可能不包含任何标志,字段宽度或精度。
p写一个实现定义的字符序列来定义一个指针。N / A

返回值

1-3)如果发生错误,则写入的字符数如果成功或为负值。

4)如果发生错误,则成功写入字符数或写入负值。如果由于buf_size限制而导致结果字符串被截断,则函数将返回如果未施加该限制的情况下将被写入的字符总数(不包括终止空字节)。

5,6)传输到输出流的字符数或负值(如果发生输出错误,运行时间约束违规错误或编码错误)。

7)写入的字符数buffer,不包括空字符(只要buffer不是空指针,bufsz并且不为零且不大于RSIZE_MAX),则不计入空字符,或者在运行时约束违规时为零,编码错误为负值

8)不包括终止空字符的字符数(只要buffer不是空指针并且bufsz不为零且不大于RSIZE_MAX),buffer如果bufsz被忽略,将被写入的字符数或者如果运行时约束违规或编码错误发生

注意

所有这些函数va_arg至少调用一次,arg返回后的值是不确定的。这些函数不会调用va_end,并且它必须由调用者完成。

vsnprintf_s不像vsprintf_s,会截断结果以适应指向的数组buffer

#include <stdio.h> #include <stdarg.h> #include <time.h> void debug_log(const char *fmt, ...) { struct timespec ts; timespec_get(&ts, TIME_UTC char time_buf[100]; size_t rc = strftime(time_buf, sizeof time_buf, "%D %T", gmtime(&ts.tv_sec) snprintf(time_buf + rc, sizeof time_buf - rc, ".%06ld UTC", ts.tv_nsec / 1000 va_list args1; va_start(args1, fmt va_list args2; va_copy(args2, args1 char buf[1+vsnprintf(NULL, 0, fmt, args1)]; va_end(args1 vsnprintf(buf, sizeof buf, fmt, args2 va_end(args2 printf("%s [debug]: %s\n", time_buf, buf } int main(void) { debug_log("Logging, %d, %d, %d", 1, 2, 3 }

可能的输出:

02/20/15 21:58:09.072683 UTC [debug]: Logging, 1, 2, 3