C-style file input/output---formatted input/output---(std::vprintf, std::vfprintf, std::vsprintf, std::vsnprintf)

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 vlistthe 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 - 1characters. The resulting string will be null-terminated unless buf_sizeis zero. If buf_sizeis zero, nothing is written and buffercan 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:

  • introduced %characters
  • (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​ ,则转换结果无字符。 在替用实现中若被转换值为非零则结果有 0x0X 前缀。

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 转换样式使用 [-]0xh.hhhp±d
A 转换样式使用 [-]0Xh.hhhP±d
若参数是正规化的浮点值,则首个十六进制数位非 0 。 若值为 ​0​ ,则指数亦为 ​0​ 。 精度指定小数点字符后出现的最小数位数。 默认精度足以准确表示该值。 在替用实现中即使没有小数点后数位也写小数点。 无穷大和非数的转换样式见注意。

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

转换浮点数为十进制小数或十进制指数记法,依赖于值和精度

g 转换样式将进行带样式 ef 的转换。
G 转换样式将进行带样式 EF 的转换。
P 等于精度,若它非零,若精度未指定则为 6 ,若精度为 ​0​ 则等于 1 。然后,若带样式 E 的转换会有指数 X ,则:

  • P > X ≥ −4 ,则转换带 fF 风格,及精度 P − 1 − X
  • 否则,转换带 eE 风格,及精度 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

浮点转换函数转换无穷大到 infinfinity 。使用哪个是实现定义的。

非数转换成 nannan(char_sequence) 。使用哪个是实现定义的。

转换 FEGA 替代上面输出 INFINFINITYNAN

尽管 %c 期待 int 参数,传递 char 是安全的,因为在调用变参数函数时发生整数提升。

定宽整数类型( int8_t 等)的正确转换指定定义于头文件 <cinttypes> (尽管 PRIdMAX 、 PRIuMAX 等就是 %jd%ju 等的别名)。

内存写入转换指定符 %n 是安全漏洞的常见目标,这里格式字符串依赖用户输入,而有边界检查的 printf_s 系列函数不支持此转换指定符。

在每个转换指定符的行动后有一个序列点;这允许于同一变量多次存入 %n 的结果,并在同一此调用中打印出先前以 %n 存储的值。

若转换指定非法,则行为未定义。

vlist - 含有要打印数据的可变参数列表

返回值

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;
}

输出

Guess you like

Origin blog.csdn.net/qq_40788199/article/details/132796015