
std::format 为什么比 sprintf 更安全
因为 std::format 是类型安全的:编译期检查参数个数和类型,不会出现 sprintf(buf, "%s %d", str) 少传参数导致的未定义行为;也不用担心缓冲区溢出——它返回 std::string 或 std::string_view(C++23),完全绕过手动管理内存。
基本用法:和 Python f-string 类似但更严格
必须显式写占位符,不支持隐式位置;默认按顺序匹配,也可用索引或名称。注意:C++20 只支持**位置索引**({0}, {1})和**自动索引**({}),不支持命名参数(如 {name})——那是 C++23 扩展。
std::string s = std::format("Hello {}!", "world"); // 自动索引
std::string t = std::format("{0} + {1} = {2}", 2, 3, 5); // 显式索引
std::string u = std::format("{:x}", 255); // 格式说明符:十六进制
常见格式说明符怎么写(对比 printf)
语法是 {arg_id:format_spec},其中 format_spec 结构为 [fill][align][width][.precision][type]。和 printf 的差异点很实际:
-
{:d}等价于%d,但{}默认就是十进制整数,不用写:d -
{:.2f}控制浮点数小数位(printf是%.2f),但注意:它对double默认输出 6 位小数,不是“保留两位”而是“总精度”,要精确控制请用{:.2f}(此时才是小数点后两位) -
{:08x}表示 8 位宽、左补零、小写十六进制(printf是%08x) -
{:>10}右对齐、最小宽度 10(printf没直接等价,得靠%10s,但不通用)
错误写法示例:{:05.2f} 合法,但 {:.2f05} 非法——顺序不能错。
立即学习“C++免费学习笔记(深入)”;
编译和链接要注意什么
std::format 在 GCC 13+ / Clang 15+ / MSVC 19.32+ 中可用,但默认可能不启用:
- Clang 需加
-std=c++20 -stdlib=libc++(若用 libc++)或确保 libstdc++ 版本够新 - MSVC 需开启
/std:c++20,且项目设置中启用 C++20 标准库(某些旧版本需定义_HAS_CXX20=1) - 链接时若报
undefined reference to std::format,大概率是标准库没导出该符号——GCC 12 及更早版本的 libstdc++ 不提供std::format实现(只声明),必须升级到 GCC 13+ 或改用 fmt 库(它是std::format的参考实现,兼容性更好)
最稳妥的做法:开发阶段用 fmt::format,上线前确认编译器/标准库支持再切回 std::format——毕竟连 GCC 官方都建议“暂时优先使用 fmt”。










