fmtlib/fmt

GitHub Trending (daily) 工具

摘要

fmtlib/fmt 是一个开源的 C++ 格式化库,提供快速且安全的替代方案,用于 C stdio 和 C++ iostreams,并实现了 C++20 的 std::format 和 C++23 的 std::print。

一个现代化的格式化库
查看原文
查看缓存全文

缓存时间: 2026/09/02 17:44

fmtlib/fmt

来源:https://github.com/fmtlib/fmt
图片
图片
图片
fmt 在 oss-fuzz 上持续进行模糊测试
OpenSSF 最佳实践
图片
在 StackOverflow 上使用标签 fmt 提问(https://stackoverflow.com/questions/tagged/fmt)
支持乌克兰(https://novaukraine.org/)

{fmt} 是一个开源格式化库,为 C 标准 I/O 和 C++ iostream 提供快速且安全的替代方案。
文档(https://fmt.dev)
速查表(https://hackingcpp.com/cpp/libs/fmt.html)
问答:在 StackOverflow 上使用标签 fmt 提问(https://stackoverflow.com/questions/tagged/fmt)。
在 Compiler Explorer 中尝试 {fmt}(https://godbolt.org/z/8Mx1EW73v)。

特性

  • 简单的格式化 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)
  • 格式化字符串语法(https://fmt.dev/latest/syntax/)类似于 Python 的 format(https://docs.python.org/3/library/stdtypes.html#str.format)
  • 快速 IEEE 754 浮点数格式化,使用 Dragonbox(https://github.com/jk-jeon/dragonbox)算法,确保正确舍入、简短和往返转换保证
  • 可移植的 Unicode 支持
  • 安全的 printf 实现(https://fmt.dev/latest/api/#printf-api),包括用于定位参数的 POSIX 扩展
  • 可扩展性:支持用户自定义类型(https://fmt.dev/latest/api/#formatting-user-defined-types)
  • 高性能:比常见的标准库实现(如 (s)printf、iostreams、to_stringto_chars)更快,参见 速度测试每秒转换一亿个整数为字符串
  • 代码体积小,源码方面最小配置仅包含三个文件:base.hformat.hformat-inl.h;编译后代码也小;参见 编译时间和代码膨胀
  • 可靠性:库具有广泛的测试套件(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)下也能保持无警告的清洁代码库
  • 默认独立于区域设置
  • 可选的仅头文件配置,通过 FMT_HEADER_ONLY 宏启用

详情请参阅文档(https://fmt.dev)。

示例

输出到标准输出(运行 (https://godbolt.org/z/Tevcjh))

#include <fmt/core.h>  

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 <fmt/chrono.h>  
#include <chrono>  

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 <fmt/ranges.h>  
#include <vector>  

int main() {  
    std::vector<int> 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 <fmt/os.h>  

int main() {  
    auto out = fmt::output_file("guide.txt");  
    out.print("Don't {}", "Panic");  
}  

这可以fprintf 快达 9 倍

带颜色和文本样式的打印

#include <fmt/color.h>  

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

基准测试

速度测试

库名方法运行时间,秒
libcprintf0.66
libc++std::ostream1.63
{fmt} 12.1fmt::print0.44
Boost Format 1.88boost::format3.89
Folly Formatfolly::format1.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)。

在 IEEE 754 floatdouble 格式化方面,{fmt} 比 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://fmt.dev/unknown_mac64_clang12.0.html)

编译时间和代码膨胀

来自 [format-benchmark][bench] 的脚本 [bloat-test.py][test] 测试非平凡项目的编译时间和代码膨胀。它生成 100 个翻译单元,并在每个单元中使用 printf() 或其替代方法五次,以模拟一个中等规模的项目。
生成的可执行文件大小和编译时间(Apple clang 版本 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma,三次最佳结果)如下表所示。
[test]: https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py
[bench]: https://github.com/fmtlib/format-benchmark

优化构建(-O3)

方法编译时间,秒可执行文件大小,KiB去除符号后大小,KiB
printf1.65450
IOStreams28.49884
{fmt} 11222685.05450
tinyformat32.6164136
Boost Format55.0530317

{fmt} 编译速度快,在每次调用的二进制大小方面与 printf 相当(在此系统上误差范围内)。

非优化构建

方法编译时间,秒可执行文件大小,KiB去除符号后大小,KiB
printf1.45450
IOStreams27.08868
{fmt} 11222684.78784
tinyformat28.1185145
Boost Format38.9678381

libclib(std)c++libfmt 均作为共享库链接,以仅比较格式化函数开销。Boost Format 是仅头文件库,因此不提供任何链接选项。

运行测试

请参阅构建库(https://fmt.dev/latest/get-started/#building-from-source)以了解如何构建库和运行单元测试的说明。
基准测试位于单独的仓库 format-benchmark(https://github.com/fmtlib/format-benchmark),因此要运行基准测试,您首先需要克隆此仓库并使用 CMake 生成 Makefile:
$ 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)检查,如果配置得当,能够将 printffprintf 的出现转换为 fmt::print。(默认情况下转换为 std::print。)

使用此库的知名项目

  • 0 A.D.(https://play0ad.com/):一个免费、开源、跨平台的即时战略游戏
  • AMPL/MP(https://github.com/ampl/mp):一个用于数学规划的开源库
  • Apple 的 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 引擎的可移植开源实现
  • 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/):高性能比特币全节点
  • 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/):一个兼容大多数 Ultima Online 客户端的 MMO 服务器
  • 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(https://github.com/rpclib/rpclib):一个现代的 C++ msgpack-RPC 服务器和客户端库
  • Salesforce Analytics Cloud(https://www.salesforce.com/analytics-cloud/overview/):商业智能软件
  • Scylla(https://www.scylladb.com/):一个兼容 Cassandra 的 NoSQL 数据存储,可在单台服务器上处理每秒 100 万笔事务
  • Seastar(https://seastar.io/):一个用于现代硬件上高性能服务器应用程序的先进开源 C++ 框架
  • spdlog(https://github.com/gabime/spdlog):超快的 C++ 日志库
  • Stellar(https://www.stellar.org/):金融平台
  • Touch Surgery(https://www.touchsurgery.com/):手术模拟器
  • TrinityCore(https://github.com/TrinityCore/TrinityCore):开源 MMORPG 框架
  • 🐙 userver framework(https://userver.tech/):一个开源的异步框架,具有丰富的抽象和数据库驱动程序
  • Windows Terminal(https://github.com/microsoft/terminal):新的 Windows 终端

更多…(https://github.com/search?q=fmtlib&type=Code)
如果您知道其他使用此库的项目,请通过电子邮件或提交 issue(https://github.com/fmtlib/fmt/issues)告知我。

维护者

{fmt} 库由 Victor Zverovich(vitaut(https://github.com/vitaut))维护,并得到许多其他人的贡献。部分姓名请参阅贡献者(https://github.com/fmtlib/fmt/graphs/contributors)和发布版本(https://github.com/fmtlib/fmt/releases)。如果您的贡献未列出或错误提及,请告知我们,我们会进行修正。

相似文章

C++26 中 std::format 的改进

Lobsters Hottest

C++26 标准对 std::format 库进行了多项改进,包括直接指针格式化、路径格式化、constexpr 支持,以及为 std::println 新增的空行重载。

I want extern "fil-c"

Lobsters Hottest

作者主张一种讲 Fil-C ABI 的 Rust FFI,使其能够与重新编译的 C/C++ 库安全互操作,并呼吁 Rust、Fil-C、Zig 和 Nix/filnix 社区之间进行跨生态协作。