标准库头文件 format C++ 20
说明
文本格式化库提供 printf 函数族的安全且可扩展的替用品。有意使之补充既存的 C++ I/O 流库并复用其基础设施,例如对用户定义类型重载的流插入运算符。
头文件
#include <format>
函数定义
template<class... Args> std::string format(std::string_view fmt, const Args&... args); template<class... Args> std::wstring format(std::wstring_view fmt, const Args&... args); template<class... Args> std::string format(const std::locale& loc, std::string_view fmt, const Args&... args); template<class... Args> std::wstring format(const std::locale& loc, std::wstring_view fmt, const Args&... args);
按照格式字符串 fmt 格式化 args ,并返回作为 string 的结果。 loc 若存在,则用于本地环境特定的格式化。
参数说明
fmt – 表示格式字符串的字符串视图。
格式字符串由以下内容组成:
- 通常字符(除了 { 与 } ),它们被不加修改地复制到输出
- 转义序列 {{ 与 }} ,它们在输出中被分别替换成 { 与 }
- 替换域
每个替换域拥有下列格式:
- 引入的 { 字符
- (可选) arg-id ,一个非负数
- (可选) 冒号( : )后随格式说明
- 终止的 } 字符
arg-id 指定用于格式化其值的 args 中的参数的下标;若省略 arg-id ,则按顺序使用参数。格式字符串中的 arg-id 必须全部存在或全部被省略。混合手动和自动指定下标是错误。
格式说明由对应参数特化的 std::formatter 定义。
- 对于基本类型和标准字符串类型,格式说明为标准格式说明
- 对于标准日期和时间类型,格式说明为 chrono 格式说明
- 对于用户定义类型,格式说明由用户定义的 std::formatter 特化决定
args… – 要格式化的参数
loc – 用于本地环境特定格式化的 std::locale
返回值
保有格式化结果的 string 对象。
异常
若 fmt 对于提供的参数不是合法的格式字符串则抛出 std::format_error 。并且会传播任何格式化器所抛的异常。
注意,提供多于格式字符串所要求的参数不是错误:
std::format("{} {}!", "Hello", "world", "something"); // OK :产生 "Hello world!"
填充与对齐
基本格式:
填充与对齐(可选) 符号(可选) <em>#(可选) 0(可选) 宽度(可选) 精度(可选) L(可选) 类型(可选)</em>
填充与对齐 是一个可选的填充字符(可为任何 { 或 } 外的的字符),后随对齐选项 < 、 > 、 ^ 之一。对齐选项的意义如下:
- < :强制域在可用空间内左对齐。这在使用非整数非浮点显示类型时为默认。
- > :强制域在可用空间内右对齐。这在使用整数或浮点显示类型时为默认。
- ^ :强制域在可用空间中央,通过在值的前面插入 n/2 向下取整个字符,后面插入 n/2 向上取整个字符,其中 n 是待插入的总字符数。
char c = 120; auto s0 = std::format("{:6}", 42); // s0 的值为 " 42" auto s1 = std::format("{:6}", 'x'); // s1 的值为 "x " auto s2 = std::format("{:*<6}", 'x'); // s2 的值为 "x*****" auto s3 = std::format("{:*>6}", 'x'); // s3 的值为 "*****x" auto s4 = std::format("{:*^6}", 'x'); // s4 的值为 "**x***" auto s5 = std::format("{:6d}", c); // s5 的值为 " 120" auto s6 = std::format("{:6}", true); // s6 的值为 "true "
符号、 # 与 0
符号 选项能为下列之一:
- + :指示符号应该一同用于非负数和负数。在非负数的输出值前插入 + 号。
- – :指示符号应该仅用于负数(这是默认行为)。
- 空格:指示应对非负数使用前导空格,而对负数使用负号。
负零被当作负数。符号 选项应用于浮点无穷大和 NaN 。
double inf = std::numeric_limits<double>::infinity(); double nan = std::numeric_limits<double>::quiet_NaN(); auto s0 = std::format("{0:},{0:+},{0:-},{0: }", 1); // s0 的值为 "1,+1,1, 1" auto s1 = std::format("{0:},{0:+},{0:-},{0: }", -1); // s1 的值为 "-1,-1,-1,-1" auto s2 = std::format("{0:},{0:+},{0:-},{0: }", inf); // s2 的值为 "inf,+inf,inf, inf" auto s3 = std::format("{0:},{0:+},{0:-},{0: }", nan); // s3 的值为 "nan,+nan,nan, nan"
formatter – 自定义的类型扩展
formatter 的被启用特化对给定类型定义格式化规则。被启用特化必须满足格式化器 (Formatter) 要求。特别是,它们定义成员函数或函数模板 parse 与 format 。
#include <format> #include <iostream> // 类型 T 的包装 template<class T> struct Box { T value; }; // 能用被包装值的格式说明格式化包装 Box<T> template<class T, class CharT> struct std::formatter<Box<T>, CharT> : std::formatter<T, CharT> { // 从基类继承 parse() // 通过以被包装值调用基类实现定义 format() template<class FormatContext> auto format(Box<T> t, FormatContext& fc) { return std::formatter<T, CharT>::format(t.value, fc); } }; int main() { Box<int> v = { 42 }; std::cout << std::format("{:#x}", v); }
输出: 0x2a
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 如何设计一个 C++ 的类
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论