跳到主要内容
版本:Next

format

std::format 是 C++20 引入的现代化字符串格式化函数,灵感来自 Python 的 str.format() 和 Rust 的 format!。它替代了 sprintfstringstream 等传统方式,既安全又高效。

头文件与基本特征

#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;
}

使用注意

  1. 需要编译器支持 C++20(GCC 13+ / Clang 14+ / MSVC 16.10+)。
  2. 格式串在编译期检查,拼写错误会直接编译报错。
  3. 自定义类型可通过特化 std::formatter 支持 format
  4. format 返回 std::string,需要频繁输出时用 format_to 减少分配。

小结

std::format 理应是你在 C++20 项目中做字符串格式化时的第一选择。比 sprintf 安全,比 stringstream 简洁,比字符串拼接直觉。C++23 进一步引入 std::print 直接输出。