format
std::format 是 C++20 引入的现代化字符串格式化函数,灵感来自 Python 的 str.format() 和 Rust 的 format!。它替代了 sprintf、stringstream 等传统方式,既安全又高效。
头文件与基本特征
#include <format>
| 特征 | 说明 |
|---|---|
| 风格 | 类 Python {} 占位符 |
| 类型安全 | 编译期检查格式串与参数匹配 |
| 性能 | 通常比 stringstream 更快 |
| 替代 | sprintf(不安全)、stringstream(冗长) |
基本用法
#include <format>
#include <iostream>
#include <string>
int main() {
std::string s = std::format("Hello, {}!", "world");
std::cout << s << '\n'; // Hello, world!
// 带编号的占位符可复用
std::cout << std::format("{1} {0} {1}", "world", "hello") << '\n';
// hello world hello
// 格式说明符
std::cout << std::format("pi = {:.2f}", 3.14159) << '\n'; // pi = 3.14
std::cout << std::format("hex: {:#x}", 255) << '\n'; // hex: 0xff
std::cout << std::format("{:*^10}", "hi") << '\n'; // ****hi****
return 0;
}
常用格式说明符
| 说明符 | 示例 | 效果 |
|---|---|---|
{:d} | format("{}", 42) | 十进制整数 |
{:#x} | format("{:#x}", 255) | 0xff |
{:.2f} | format("{:.2f}", 3.14) | 保留两位小数 |
{:>10} | format("{:>10}", "hi") | 右对齐宽度 10 |
{:<10} | format("{:<10}", "hi") | 左对齐宽度 10 |
{:^10} | format("{:^10}", "hi") | 居中对齐宽度 10 |
与旧方式的对比
// C 风格:不安全,类型不匹配时 UB
char buf[64];
sprintf(buf, "value = %d", 42);
// C++98 风格:冗长
std::ostringstream oss;
oss << "value = " << 42;
std::string s = oss.str();
// C++20:简洁安全
std::string s = std::format("value = {}", 42);
std::format_to —— 输出到迭代器
#include <format>
#include <iostream>
#include <iterator>
int main() {
std::format_to(std::ostreambuf_iterator(std::cout), "x = {}, y = {}\n", 10, 20);
return 0;
}
使用注意
- 需要编译器支持 C++20(GCC 13+ / Clang 14+ / MSVC 16.10+)。
- 格式串在编译期检查,拼写错误会直接编译报错。
- 自定义类型可通过特化
std::formatter支持format。 format返回std::string,需要频繁输出时用format_to减少分配。
小结
std::format 理应是你在 C++20 项目中做字符串格式化时的第一选择。比 sprintf 安全,比 stringstream 简洁,比字符串拼接直觉。C++23 进一步引入 std::print 直接输出。