C++ 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio> 头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数,而 <cwchar>头文件提供有宽字符输入/输出能力的函数。
有格式输入/输出
打印有格式输出到 stdout、文件流或缓冲区
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) | (C++11 起) |
从给定位置加载数据,转换为字符串等价版本,并将结果写入各种池。
1) 写结果到 stdout 。
2) 写结果到文件流 stream
。
3) 写结果到字符串 buffer
。
4) 写结果到字符串 buffer
。至多写 buf_size
- 1 个字符。产生的字符串会以空字符终止,除非 buf_size
为零。若 buf_size
为零,则不写入任何内容,且 buffer
可以是空指针,然而依旧计算返回值(会写入的字符数,不包含空终止符)并返回。
若调用 sprintf
或 snprintf
导致在重叠的对象间发生复制,则行为未定义。(例如 sprintf(buf, "%s text", buf); )
参数
stream | - | 要写入的输出文件流 |
buffer | - | 指向要写入的字符串的指针 |
buf_size | - | 写入至多 buf_size - 1 个字符,再加上空终止符 |
format | - | 指向指定如何转译数据的空终止多字节字符串的指针。 格式字符串由普通多字节字符(除了
|
下列格式指定符可用:
|
浮点转换函数转换无穷大到 非数转换成 转换 尽管 定宽整数类型( int8_t 等)的正确转换指定定义于头文件 <cinttypes> (尽管 PRIdMAX 、 PRIuMAX 等就是 内存写入转换指定符 %n 是安全漏洞的常见目标,这里格式字符串依赖用户输入,而有边界检查的 在每个转换指定符的行动后有一个序列点;这允许于同一变量多次存入 %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;
}