fmtlib/fmt

GitHub: fmtlib/fmt

{fmt} 是一个开源的 C++ 格式化库,提供了比标准库更快、更安全且可扩展的文本处理方案。

Stars: 23301 | Forks: 2834

{fmt} [![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/3fdc327862010134.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux) [![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/9a4267a468010134.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos) [![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/21273f5e94010135.svg)](https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows) [![fmt is continuously fuzzed at oss-fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?\%0Acolspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\%0ASummary&q=proj%3Dfmt&can=1) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8880/badge)](https://www.bestpractices.dev/projects/8880) [![image](https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge)](https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt) [![Ask questions at StackOverflow with the tag fmt](https://img.shields.io/badge/stackoverflow-fmt-blue.svg)](https://stackoverflow.com/questions/tagged/fmt) **{fmt}** 是一个开源格式化库,提供了快速且安全的 C stdio 和 C++ iostreams 替代方案。 [文档](https://fmt.dev) [速查表](https://hackingcpp.com/cpp/libs/fmt.html) 问答:在 [StackOverflow 上使用 fmt 标签](https://stackoverflow.com/questions/tagged/fmt) 提问。 在 [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v) 中试用 {fmt}。 # 功能特性 - 简单的 [格式化 API](https://fmt.dev/latest/api/),支持用于本地化的位置参数 - [C++20 std::format](https://en.cppreference.com/w/cpp/utility/format) 和 [C++23 std::print](https://en.cppreference.com/w/cpp/io/print) 的实现 - 类似于 Python [format](https://docs.python.org/3/library/stdtypes.html#str.format) 的 [格式字符串语法](https://fmt.dev/latest/syntax/) - 快速的 IEEE 754 浮点数格式化器,使用 [Dragonbox](https://github.com/jk-jeon/dragonbox) 算法保证正确舍入、最短长度和往返一致性 - 可移植的 Unicode 支持 - 安全的 [printf 实现](https://fmt.dev/latest/api/#printf-formatting),包括用于位置参数的 POSIX 扩展 - 可扩展性:[支持用户定义类型](https://fmt.dev/latest/api/#formatting-user-defined-types) - 高性能:比常见的标准库 `(s)printf`、iostreams、`to_string` 和 `to_chars` 实现更快,参见 [速度测试](#speed-tests) 和 [每秒转换一亿个整数为字符串](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html) - 较小的代码体积:最小配置的源代码仅包含三个文件 `base.h`、`format.h` 和 `format-inl.h`,且编译后的代码也很小;参见 [编译时间和代码膨胀](#compile-time-and-code-bloat) - 可靠性:该库拥有广泛的 [测试](https://github.com/fmtlib/fmt/tree/master/test) 并 [持续进行模糊测试](https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1) - 安全性:该库是完全类型安全的,格式字符串中的错误可以在编译时报告,自动内存管理防止缓冲区溢出错误 - 易用性:小巧独立的代码库,无外部依赖,宽松的 MIT [许可证](https://github.com/fmtlib/fmt/blob/master/LICENSE) - [可移植性](https://fmt.dev/latest/#portability),跨平台输出一致,并支持较旧的编译器 - 整洁且无警告的代码库,即使在 `-Wall -Wextra -pedantic` 等高警告级别下 - 默认情况下区域设置独立 - 可选的 header-only 配置,通过 `FMT_HEADER_ONLY` 宏启用 有关更多详细信息,请参阅 [文档](https://fmt.dev)。 # 示例 **打印到 stdout** ([运行](https://godbolt.org/z/Tevcjh)) ``` #include int main() { fmt::print("Hello, world!\n"); } ``` **格式化字符串** ([运行](https://godbolt.org/z/oK8h33)) ``` std::string s = fmt::format("The answer is {}.", 42); // s == "The answer is 42." ``` **使用位置参数格式化字符串** ([运行](https://godbolt.org/z/Yn7Txe)) ``` std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy"); // s == "I'd rather be happy than right." ``` **打印日期和时间** ([运行](https://godbolt.org/z/c31ExdY3W)) ``` #include int main() { auto now = std::chrono::system_clock::now(); fmt::print("Date and time: {}\n", now); fmt::print("Time: {:%H:%M}\n", now); } ``` 输出: ``` Date and time: 2023-12-26 19:10:31.557195597 Time: 19:10 ``` **打印容器** ([运行](https://godbolt.org/z/MxM1YqjE7)) ``` #include #include int main() { std::vector v = {1, 2, 3}; fmt::print("{}\n", v); } ``` 输出: ``` [1, 2, 3] ``` **在编译时检查格式字符串** ``` std::string s = fmt::format("{:d}", "I am not a number"); ``` 这在 C++20 中会产生编译时错误,因为 `d` 对于字符串来说是一个无效的格式说明符。 **从单线程写入文件** ``` #include int main() { auto out = fmt::output_file("guide.txt"); out.print("Don't {}", "Panic"); } ``` 这可能 [比 `fprintf` 快达 9 倍]( http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html)。 **使用颜色和文本样式打印** ``` #include int main() { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "Hello, {}!\n", "world"); fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | fmt::emphasis::underline, "Olá, {}!\n", "Mundo"); fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, "你好{}!\n", "世界"); } ``` 在支持 Unicode 的现代终端上的输出: ![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/58ce00289d010137.png) # 基准测试 ## 速度测试 | Library | Method | Run Time, s | |-------------------|---------------|-------------| | libc | printf | 0.66 | | libc++ | std::ostream | 1.63 | | {fmt} 12.1 | fmt::print | 0.44 | | Boost Format 1.88 | boost::format | 3.89 | | Folly Format | folly::format | 1.28 | {fmt} 是基准测试方法中最快的,比 `printf` 快约 50%。 上述结果是通过在 macOS 15.6.1 上使用 `clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT` 构建 `tinyformat_test.cpp` 生成的,并取三次运行中的最佳结果。在测试中,格式字符串 `"%0.10f:%04d:%+g:%s:%p:%c:%%\n"` 或等效字符串被填充 2,000,000 次,输出发送到 `/dev/null`;有关更多详细信息,请参阅 [源代码](https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc)。 {fmt} 在 IEEE754 `float` 和 `double` 格式化方面比 `std::ostringstream` 和 `sprintf` 快 20-30 倍 ([dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark)),并且比 [double-conversion](https://github.com/google/double-conversion) 和 [ryu](https://github.com/ulfjack/ryu) 更快: [![image](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/aeb59780e0010139.png)](https://fmt.dev/unknown_mac64_clang12.0.html) ## 编译时间和代码膨胀 来自 [format-benchmark][bench] 的脚本 [bloat-test.py][test] 测试了非平凡项目的编译时间和代码膨胀。它生成 100 个翻译单元,并在每个单元中使用 `printf()` 或其替代方法五次,以模拟中型项目。生成的可执行文件大小和编译时间(Apple clang version 15.0.0 (clang-1500.1.0.2.5),macOS Sonoma,三次运行中的最佳结果)如下表所示。 **优化构建 (-O3)** | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB | |-----------------|-----------------|----------------------|--------------------| | printf | 1.6 | 54 | 50 | | IOStreams | 28.4 | 98 | 84 | | {fmt} `1122268` | 5.0 | 54 | 50 | | tinyformat | 32.6 | 164 | 136 | | Boost Format | 55.0 | 530 | 317 | {fmt} 编译速度快,并且在每次调用的二进制大小方面与 `printf` 相当(在该系统上存在舍入误差)。 **非优化构建** | Method | Compile Time, s | Executable size, KiB | Stripped size, KiB | |-----------------|-----------------|----------------------|--------------------| | printf | 1.4 | 54 | 50 | | IOStreams | 27.0 | 88 | 68 | | {fmt} `1122268` | 4.7 | 87 | 84 | | tinyformat | 28.1 | 185 | 145 | | Boost Format | 38.9 | 678 | 381 | `libc`、`lib(std)c++` 和 `libfmt` 均作为共享库链接,以便仅比较格式化函数的开销。Boost Format 是一个 header-only 库,因此它不提供任何链接选项。 ## 运行测试 有关如何构建库和运行单元测试的说明,请参阅 [构建库](https://fmt.dev/latest/get-started/#building-from-source)。 基准测试位于单独的仓库 [format-benchmarks](https://github.com/fmtlib/format-benchmark) 中,因此要运行基准测试,您首先需要克隆该仓库并使用 CMake 生成 Makefiles: ``` $ git clone --recursive https://github.com/fmtlib/format-benchmark.git $ cd format-benchmark $ cmake . ``` 然后您可以运行速度测试: ``` $ make speed-test ``` 或膨胀测试: ``` $ make bloat-test ``` # 代码迁移 [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v18 提供了 [modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html) 检查,如果配置得当,它能够将 `printf` 和 `fprintf` 的出现转换为 `fmt::print`。(默认情况下它转换为 `std::print`。) # 使用此库的知名项目 - [0 A.D.](https://play0ad.com/):一款免费、开源、跨平台的即时战略游戏 - [AMPL/MP](https://github.com/ampl/mp):一个用于数学规划的开源库 - [Apple's FoundationDB](https://github.com/apple/foundationdb):一个开源的分布式事务键值存储 - [Aseprite](https://github.com/aseprite/aseprite):动画精灵编辑器和像素画工具 - [AvioBook](https://www.aviobook.aero/en):一套全面的飞机运营套件 - [Blizzard Battle.net](https://battle.net/):一个在线游戏平台 - [Celestia](https://celestia.space/):空间的实时 3D 可视化 - [Ceph](https://ceph.com/):一个可扩展的分布式存储系统 - [ccache](https://ccache.dev/):一个编译器缓存 - [ClickHouse](https://github.com/ClickHouse/ClickHouse):一个分析型数据库管理系统 - [ContextVision](https://www.contextvision.com/):医学成像软件 - [Contour](https://github.com/contour-terminal/contour/):一个现代终端模拟器 - [CUAUV](https://cuauv.org/):康奈尔大学的自主水下航行器 - [Drake](https://drake.mit.edu/):一个用于非线性动力系统的规划、控制和分析工具箱 (MIT) - [Envoy](https://github.com/envoyproxy/envoy):C++ L7 代理和通信总线 (Lyft) - [FiveM](https://fivem.net/):一个 GTA V 的修改框架 - [fmtlog](https://github.com/MengRao/fmtlog):一个高性能的 fmtlib 风格日志库,延迟为纳秒级 - [Folly](https://github.com/facebook/folly):Facebook 开源库 - [GemRB](https://gemrb.org/):Bioware Infinity Engine 的便携式开源实现 - [Grand Mountain Adventure](https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/):一款美丽的开放世界滑雪和单板滑雪游戏 - [HarpyWar/pvpgn](https://github.com/pvpgn/pvpgn-server):经过调整的玩家对战玩家游戏网络 - [KBEngine](https://github.com/kbengine/kbengine):一个开源 MMOG 服务器引擎 - [Keypirinha](https://keypirinha.com/):一个 Windows 上的语义启动器 - [Kodi](https://kodi.tv/)(原 xbmc):家庭影院软件 - [Knuth](https://kth.cash/):高性能 Bitcoin 全节点 - [libunicode](https://github.com/contour-terminal/libunicode/):一个现代 C++17 Unicode 库 - [MariaDB](https://mariadb.org/):关系数据库管理系统 - [Microsoft Verona](https://github.com/microsoft/verona):用于并发所有权的研究编程语言 - [MongoDB](https://mongodb.com/):分布式文档数据库 - [MongoDB Smasher](https://github.com/duckie/mongo_smasher):一个生成随机数据集的小工具 - [OpenSpace](https://openspaceproject.com/):一个开源的天体可视化框架 - [PenUltima Online (POL)](https://www.polserver.com/):一个 MMO 服务器,兼容大多数 Ultima Online 客户端 - [PyTorch](https://github.com/pytorch/pytorch):一个开源机器学习库 - [quasardb](https://www.quasardb.net/):一个分布式、高性能、关联数据库 - [Quill](https://github.com/odygrd/quill):异步低延迟日志库 - [QKW](https://github.com/ravijanjam/qkw):泛化别名以简化导航,并执行复杂的多行终端命令序列 - [redis-cerberus](https://github.com/HunanTV/redis-cerberus):一个 Redis 集群代理 - [redpanda](https://vectorized.io/redpanda):一个用 C++ 编写的、比 Kafka® 快 10 倍的关键任务系统替代品 - [rpclib](
标签:Bash脚本, C++, C++20, fmt, iostream替代, std::format, 嵌入式开发, 开源库, 搜索引擎爬虫, 数据擦除, 文本处理, 格式化库, 类型安全, 系统编程, 编码规范