C-style file input/output ---Formatted input/output --- (std::printf, std::fprintf, std::sprintf, std::snprintf)

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 output to stdout, file stream, or buffer

std::printf, 
std::fprintf, 
std::sprintf, 
std::snprintf

int printf( const char* format, ... );

(1)

int fprintf( std::FILE* stream, const char* format, ... );

(2)

int sprintf( char* buffer, const char* format, ... );

(3)

int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );

(4) (since C++11)

Loads data from a given location, converts to string equivalent, and writes 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 character. The resulting string is null-terminated unless buf_sizeis zero. If buf_sizeis zero, nothing is written, and buffercan be a null pointer, but the return value (the number of characters that will be written, excluding the null terminator) is still calculated and returned.

The behavior is undefined if calling sprintfor snprintfcauses copying between overlapping objects. (For example sprintf(buf, "%s text", buf); )

parameter

stream - The output file stream to write to
buffer - pointer to the string to write
buf_size - Write up to buf_size - 1 character, plus null terminator
format - Pointer to a null-terminated multibyte 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

参数必须是指向字符数组首元素的指针 精度指定写入最大的字符数。若未指定精度,则写每个字节直到而而不含首个空终止符。 若使用 l 指定符,则参数必须是指向 wchar_t 数组首元素的指针,数组会被转换成 char 数组,如同通过以零初始化转换状态调用 wcrtomb 。

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 存储的值。

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

... - 指定要打印数据的参数。若任何参数类型不是对应转换指定符所期望者,或若参数数量少于 format 所要求这,则行为未定义。若参数数量多于 format 所要求者,则求值后忽略额外参数

返回值

1-2) 若成功则为写入的字符数,若发生错误则为负值。

3) 若成功则为写入的字符数(不包含空终止字符),若发生错误则为负值。

4) 若成功则为会写入充分大缓冲区的字符数(不包含空终止字符),若发生错误则为负值。从而若且唯若返回值非负且小于 buf_size 才完全写入(空终止)。

注意

POSIX 规定在错误时设置 errno 。它亦指定额外的转换指定,最值得注意的是对参数重排序的支持(紧随 % 后的 n$ 指示第 n 个参数)。

以零 buf_size 和对于 buffer 的空指针调用 std::snprintf 适用于确定容纳输出的所需缓冲区大小:

const char *fmt = "sqrt(2) = %f";
int sz = std::snprintf(nullptr, 0, fmt, std::sqrt(2));
std::vector<char> buf(sz + 1); // 注意为空终止符 +1
std::snprintf(&buf[0], buf.size(), fmt, std::sqrt(2));

 调用示例

#include <cstdio>
#include <limits>
#include <cstdint>
#include <cinttypes>

int main()
{
    std::printf("Strings:\n");

    const char* s = "Hello";
    std::printf("\t[%10s]\n\t[%-10s]\n\t[%*s]\n\t[%-10.*s]\n\t[%-*.*s]\n",
                s, s, 10, s, 4, s, 10, 4, s);

    std::printf("Characters:\t%c %%\n", 65);

    std::printf("Integers\n");
    std::printf("Decimal:\t%i %d %.6i %i %.0i %+i %u\n", 1, 2, 3, 0, 0, 4, -1);
    std::printf("Hexadecimal:\t%x %x %X %#x\n", 5, 10, 10, 6);
    std::printf("Octal:\t%o %#o %#o\n", 10, 10, 4);

    std::printf("Floating point\n");
    std::printf("Rounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.5);
    std::printf("Padding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
    std::printf("Scientific:\t%E %e\n", 1.5, 1.5);
    std::printf("Hexadecimal:\t%a %A\n", 1.5, 1.5);
    std::printf("Special values:\t0/0=%g 1/0=%g\n", 0.0 / 0.0, 1.0 / 0.0);

    std::printf("Variable width control:\n");
    std::printf("right-justified variable width: '%*c'\n", 5, 'x');
    int r = std::printf("left-justified variable width : '%*c'\n", -5, 'x');
    std::printf("(the last printf printed %d characters)\n", r);

    // 定宽类型
    std::uint32_t val = std::numeric_limits<std::uint32_t>::max();
    std::printf("Largest 32-bit value is %" PRIu32 " or %#" PRIx32 "\n", val, val);
    return 0;
}

输出

Guess you like

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