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