The CI/O subset of the C++ standard library implements C-style stream input/output operations. The <cstdio> header file provides general file support and provides functions with narrow and multibyte character input/output capabilities, while the <cwchar> header file provides functions with wide character input/output capabilities.
Formatted input/output
Print formatted wide character output to stdout, a file stream, or a buffer using a variable argument list
std::vprintf,
std::vfprintf,
std::vsprintf,
std::vsnprintf
int vprintf( const char* format, va_list vlist ); |
(1) |
|
int vfprintf( std::FILE* stream, const char* format, va_list vlist ); |
(2) |
|
int vsprintf( char* buffer, const char* format, va_list vlist ); |
(3) |
|
int vsnprintf( char* buffer, std::size_t buf_size, const char* format, va_list vlist ); |
(4) |
(since C++11) |
From vlist
the various locations defined by , convert them to their string equivalents and write the results to various pools.
1) Write the result to stdout.
2) Write the results to the file stream stream
.
3) Write the result to a string buffer
.
4) Write the result to a string buffer
. Write at most buf_size - 1
characters. The resulting string will be null-terminated unless buf_size
is zero. If buf_size
is zero, nothing is written and buffer
can be a null pointer, however the return value (the number of bytes that would have been written, excluding the null terminator) is still calculated and returned.
parameter
stream |
- |
The output file stream to write to |
buffer |
- |
pointer to the string to write |
buf_size |
- |
Maximum number of characters to write |
format |
- |
Pointer to a null-terminated string that specifies how to interpret the data. The format string consists of ordinary multibyte characters (except % ) and conversion specifications, the former of which is copied to the output stream without change. Each transformation specification has the following format:
- (Optional) One or more tags that modify the conversion behavior:
- : The conversion result is left-corrected within the domain (default is right-corrected)
+ : The sign of a signed conversion is always prepended to the conversion result (default result is prepended with a negative sign only if it is negative)
- Space : If the result of signed conversion does not start with a symbol, or is empty, a leading space will be added to the result. If
+ the tag is present, spaces are ignored .
# : Convert to alternative form . The exact effects are shown in the table below, otherwise the behavior is undefined.
0 : For integer and floating point conversions, fields are padded with leading zeros instead of space characters. For integers, this tag is ignored if the precision is explicitly specified. For other transformations, using this tag results in undefined behavior. If - the tag exists, it is ignored 0 .
- (Optional) An integer value or that specifies the minimum field width
* . If requested, the result will be padded with space characters (the default), on the left when correcting right, and on the right when correcting left. When using * , specify the width with an additional parameter of type int. If the parameter value is negative, it results in the specified - label and positive domain width. (Note: This is the minimum width: the value is never truncated).
- (Optional) followed by an integer or
* or neither . indicating the precision of the conversion . In the case of using * , the precision is specified by an additional parameter of type int. If the value of this parameter is negative, it is ignored. If neither numeric nor numeric is used * , the precision is zero. The exact effect of precision is shown in the table below.
- (Optional) Length modifier specifying the parameter size
- conversion format specifier
|
The following format specifiers are available:
conversion specifier |
explain |
Parameter Type |
length modifier |
hh (C++11) |
h |
(none) |
l |
ll (C++11) |
j (C++11) |
z (C++11) |
t (C++11) |
L |
% |
Literal % . The complete conversion specification must be %% . |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
c |
Write a single character . The parameters are first converted to unsigned char. If the l modifier is used , the argument is first converted to a string, as by using %ls with the wchar_t[2] argument . |
N/A |
N/A |
int |
wint_t |
N/A |
N/A |
N/A |
N/A |
N/A |
s |
write string The parameter must be a pointer to the first element of the character array and the precision specifies the maximum number of characters to write. If precision is not specified , each byte is written up to but not including the first null terminator. If the l specifier is used, the argument must be a pointer to the first element of a wchar_t array, which is converted to a char array as if wcrtomb was called by initializing the conversion state with zero. |
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 |
有符号 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 |
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 (C++11) |
N/A |
N/A |
N/A |
N/A |
long double |
e
E |
转换浮点数为十进制指数记法。 e 转换样式使用 [-]d.ddde ±dd 。
E 转换样式使用 [-]d.dddE ±dd 。 指数至少含二个数位,仅当所需时使用更多数位。 若值为 0 ,则指数亦为 0 。 精度指定小数点字符后出现的最小数位数。 默认精度是 6 。 在替用实现中即使没有小数点后数位也写小数点。 无穷大和非数的转换样式见注意。 |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
a
A (C++11) |
转换浮点数为十六进制记法。 a 转换样式使用 [-]0x h.hhhp ±d 。
A 转换样式使用 [-]0X h.hhhP ±d 。 若参数是正规化的浮点值,则首个十六进制数位非 0 。 若值为 0 ,则指数亦为 0 。 精度指定小数点字符后出现的最小数位数。 默认精度足以准确表示该值。 在替用实现中即使没有小数点后数位也写小数点。 无穷大和非数的转换样式见注意。 |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
g
G |
转换浮点数为十进制小数或十进制指数记法,依赖于值和精度。 g 转换样式将进行带样式 e 或 f 的转换。
G 转换样式将进行带样式 E 或 F 的转换。 令 P 等于精度,若它非零,若精度未指定则为 6 ,若精度为 0 则等于 1 。然后,若带样式 E 的转换会有指数 X ,则:
- 若 P > X ≥ −4 ,则转换带
f 或 F 风格,及精度 P − 1 − X 。
- 否则,转换带
e 或 E 风格,及精度 P − 1 。
除非要求替用表示,否则末尾零会被移除,且若不留下小数部分则小数点亦被移除。 无穷大和非数的转换样式见注意。 |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
n |
返回对函数的此调用迄今为止写入的字符数。 结果被写入到参数所指向的值。 该指定不可含有任何标签、域宽或精度。 |
signed char* |
short* |
int* |
long* |
long long* |
intmax_t* |
有符号 size_t* |
ptrdiff_t* |
N/A |
p |
写定义指针的实现定义字符序列。 |
N/A |
N/A |
void* |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |
|
浮点转换函数转换无穷大到 inf 或 infinity 。使用哪个是实现定义的。 非数转换成 nan 或 nan(char_sequence) 。使用哪个是实现定义的。 转换 F 、 E 、 G 、 A 替代上面输出 INF 、 INFINITY 、 NAN 。 尽管 %c 期待 int 参数,传递 char 是安全的,因为在调用变参数函数时发生整数提升。 定宽整数类型( int8_t 等)的正确转换指定定义于头文件 <cinttypes> (尽管 PRIdMAX 、 PRIuMAX 等就是 %jd 、 %ju 等的别名)。 内存写入转换指定符 %n 是安全漏洞的常见目标,这里格式字符串依赖用户输入,而有边界检查的 printf_s 系列函数不支持此转换指定符。 在每个转换指定符的行动后有一个序列点;这允许于同一变量多次存入 %n 的结果,并在同一此调用中打印出先前以 %n 存储的值。 若转换指定非法,则行为未定义。 |
返回值
1-3) 若成功则为写入的字符数,或若出现错误则为负值。
4) 若成功则为写入的字符数,或若出现错误则为负值。若结果字符串由于 buf_size
限制被截断,则函数返回假如未强加极限则本应写入的总字节数(不包含空终止字符)。
注意
所有这些函数调用 va_arg 至少一次,返回后 arg
的值不确定。这些函数不调用 va_end ,而这必须由调用方进行。
调用示例
#include <vector>
#include <cstdio>
#include <cstdarg>
#include <ctime>
void debug_log(const char *fmt, ...)
{
auto t = std::time(nullptr);
char time_buf[100];
std::strftime(time_buf, sizeof time_buf, "%D %T", std::gmtime(&t));
va_list args1;
va_start(args1, fmt);
va_list args2;
va_copy(args2, args1);
std::vector<char> buf(1 + std::vsnprintf(nullptr, 0, fmt, args1));
va_end(args1);
std::vsnprintf(buf.data(), buf.size(), fmt, args2);
va_end(args2);
std::printf("%s [debug]: %s\n", time_buf, buf.data());
}
int main()
{
debug_log("Logging, %d, %d, %d", 1, 2, 3);
return 0;
}
输出