文本格式化库提供 printf 函数族的安全且可扩展的替用品。有意使之补充既存的 C++ I/O 流库并复用其基础设施,例如对用户定义类型重载的流插入运算符。
#include
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 指定用于格式化其值的 args 中的参数的下标;若省略 arg-id ,则按顺序使用参数。格式字符串中的 arg-id 必须全部存在或全部被省略。混合手动和自动指定下标是错误。
格式说明由对应参数特化的 std::formatter 定义。
args… - 要格式化的参数
loc - 用于本地环境特定格式化的 std::locale
保有格式化结果的 string 对象。
若 fmt 对于提供的参数不是合法的格式字符串则抛出 std::format_error 。并且会传播任何格式化器所抛的异常。
注意,提供多于格式字符串所要求的参数不是错误:
std::format("{} {}!", "Hello", "world", "something"); // OK :产生 "Hello world!"
基本格式:
填充与对齐(可选) 符号(可选) #(可选) 0(可选) 宽度(可选) 精度(可选) L(可选) 类型(可选)
填充与对齐 是一个可选的填充字符(可为任何 { 或 } 外的的字符),后随对齐选项 < 、 > 、 ^ 之一。对齐选项的意义如下:
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 "
符号 选项能为下列之一:
负零被当作负数。符号 选项应用于浮点无穷大和 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) 要求。特别是,它们定义成员函数或函数模板 parse 与 format 。
#include
#include
// 类型 T 的包装
template<class T>
struct Box {
T value;
};
// 能用被包装值的格式说明格式化包装 Box
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
参考:https://zh.cppreference.com/w/cpp/utility/format