fmt - 是一个开源格式化库,为 C stdio 和 C++ iostreams 提供了一种快速安全的替代方案。

Created at: 2012-12-08 00:26:46
Language: C++
License: NOASSERTION

..图片:: https://user-images.githubusercontent.com/ 576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png :宽度: 25% :alt: {fmt}

..图片:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg :目标: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux

..图片:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg :目标: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos

..图片:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg :目标: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows

..image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg :alt: fmt 在 oss-fuzz :target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\ colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20
Summary&q=proj%3Dfmt&can=1

..图片:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg :alt: 在 StackOverflow 上提出问题,标签为 fmt :target: https://stackoverflow.com/questions/tagged/fmt

..图片:: https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge :目标: https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt

{fmt} 是一个开源格式化库,为 C stdio 和 C++ iostreams 提供了一种快速安全的替代方案。

如果你喜欢这个项目,请考虑捐赠给帮助乌克兰战争受害者的基金之一:https://www.stopputin.net/

Documentation <https://fmt.dev>
__

Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>
__

问答:在_上提问。

StackOverflow with the tag fmt <https://stackoverflow.com/questions/tagged/fmt>

在 _ 中尝试 {fmt}。

Compiler Explorer <https://godbolt.org/z/Eq5763>

特征

  • 简单 _ 带有用于本地化的位置参数
    format API <https://fmt.dev/latest/api.html>
  • 实施
    C++20 std::format <https://en.cppreference.com/w/cpp/utility/format>
    __
  • Format string syntax <https://fmt.dev/latest/syntax.html>
    _ 类似于 Python 的
    format <https://docs.python.org/3/library/stdtypes.html#str.format>
    _
  • 快速 IEEE 754 浮点格式化程序,使用 _ 算法提供正确的舍入、短路和往返保证
    Dragonbox <https://github.com/jk-jeon/dragonbox>
  • 可移植的 Unicode 支持
  • 安全 _ 包括用于位置参数的 POSIX 扩展
    printf implementation <https://fmt.dev/latest/api.html#printf-formatting>
  • 扩展:
    support for user-defined types <https://fmt.dev/latest/api.html#formatting-user-defined-types>
    _
  • 高性能:比 、iostream 和 的常见标准库实现更快,请参见 _ 和
    (s)printf
    to_string
    to_chars
    Speed tests
    Converting a hundred million integers to strings per second <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>
    _
  • 代码大小小,源代码方面,最小配置仅包含三个文件、、、 和编译代码;看
    core.h
    format.h
    format-inl.h
    Compile time and code bloat
    _
  • 可靠性:该库具有广泛的 _ 集,并且
    tests <https://github.com/fmtlib/fmt/tree/master/test>
    continuously fuzzed <https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20 Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>
    _
  • 安全性:库是完全类型安全的,格式字符串中的错误可以在编译时报告,自动内存管理可防止缓冲区溢出错误
  • 易用性:小型独立代码库,无外部依赖,宽松的 MIT
    license <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>
    _
  • Portability <https://fmt.dev/latest/index.html#portability>
    _ 具有跨平台的一致输出并支持较旧的编译器
  • 即使在高警告级别(例如
    -Wall -Wextra -pedantic
  • 默认情况下与区域设置无关
  • 使用宏启用的可选仅标头配置
    FMT_HEADER_ONLY

有关更多详细信息,请参阅 _。

documentation <https://fmt.dev>

例子

打印到标准输出 (

run <https://godbolt.org/z/Tevcjh>
_)

..代码:: c++

#include <fmt/core.h>

int main() {
  fmt::print("Hello, world!\n");
}

设置字符串格式 (

run <https://godbolt.org/z/oK8h33>
_)

..代码:: c++

std::string s = fmt::format("The answer is {}.", 42);
// s == "The answer is 42."

使用位置参数设置字符串格式 (

run <https://godbolt.org/z/Yn7Txe>
_)

..代码:: c++

std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
// s == "I'd rather be happy than right."

打印计时持续时间 (

run <https://godbolt.org/z/K8s4Mc>
_)

..代码:: c++

#include <fmt/chrono.h>

int main() {
  using namespace std::literals::chrono_literals;
  fmt::print("Default format: {} {}\n", 42s, 100ms);
  fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
}

输出::

Default format: 42s 100ms
strftime-like format: 03:15:30

打印容器 (

run <https://godbolt.org/z/MxM1YqjE7>
_)

..代码:: c++

#include <vector>
#include <fmt/ranges.h>

int main() {
  std::vector<int> v = {1, 2, 3};
  fmt::print("{}\n", v);
}

输出::

[1, 2, 3]

在编译时检查格式字符串

..代码:: c++

std::string s = fmt::format("{:d}", "I am not a number");

这会在 C++20 中给出编译时错误,因为字符串的格式说明符无效。

d

从单个线程写入文件

..代码:: c++

#include <fmt/os.h>

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

这可以是 _。

5 to 9 times faster than fprintf <http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>

使用颜色和文本样式打印

..代码:: c++

#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, "Hello, {}!\n", "мир");
  fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "Hello, {}!\n", "世界");
}

现代终端上的输出:

..图片:: https://user-images.githubusercontent.com/ 576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png

基准

速度测试

================= ============= ===========
Library           Method        Run Time, s
================= ============= ===========
libc              printf          0.91
libc++            std::ostream    2.49
{fmt} 9.1         fmt::print      0.74
Boost Format 1.80 boost::format   6.26
Folly Format      folly::format   1.87
================= ============= ===========

{fmt} is the fastest of the benchmarked methods, ~20% faster than ``printf``.

The above results were generated by building ``tinyformat_test.cpp`` on macOS
12.6.1 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
further details refer to the `source
<https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_.

{fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on
IEEE754 ``float`` and ``double`` formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
and faster than `double-conversion <https://github.com/google/double-conversion>`_ and
`ryu <https://github.com/ulfjack/ryu>`_:

.. image:: https://user-images.githubusercontent.com/576385/
           95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png
   :target: https://fmt.dev/unknown_mac64_clang12.0.html

Compile time and code bloat

脚本 _ from _ 测试编译时间,并为重要的项目编写代码膨胀。它生成 100 个翻译单元,并在每个单元中使用或替代五次来模拟中型项目。下表显示了生成的可执行文件大小和编译时间(Apple LLVM 版本 8.1.0 (clang-802.0.42)、macOS Sierra,三选一)。

bloat-test.py <https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>
format-benchmark <https://github.com/fmtlib/format-benchmark>
printf()

优化构建 (-O3)

============== ==============================================================================================================================================================================================================================================================================================================================================================================================================================================================================6 29 26 printf+string 16.4 29 26 iostreams 31.1 59 55 {fmt} 19.0 37 34 Boost 格式 91.9 226 203 愚蠢格式 115.7 101 88 ==================================================================================

如你所见,与 iostream 相比,{fmt} 在生成的二进制代码大小方面减少了 60% 的开销,并且非常接近 .增强格式和愚蠢格式的开销最大。

printf

printf+string
与后者相同,但有一个额外的包含来衡量后者的开销。
printf
<string>

未优化的构建

============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================2 33 30 printf+string 16.0 33 30 iostreams 28.3 56 52 {fmt} 18.2 59 50 增强格式 54.1 365 303 愚蠢格式 79.9 445 430 ==============================================================================

libc
、 和 都作为共享库链接,仅用于比较格式化函数开销。增强格式是一个仅标头库,因此它不提供任何链接选项。
lib(std)c++
libfmt

运行测试

Please refer to `Building the library`__ for instructions on how to build
the library and run the unit tests.

__ https://fmt.dev/latest/usage.html#building-the-library

Benchmarks reside in a separate repository,
`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
so to run the benchmarks you first need to clone this repository and
generate Makefiles with CMake::

    $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
    $ cd format-benchmark
    $ cmake .

Then you can run the speed test::

    $ make speed-test

or the bloat test::

    $ make bloat-test

Migrating code
--------------

`clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`_ v17 (not yet
released) provides the `modernize-use-std-print
<https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html>`_
check that is capable of converting occurrences of ``printf`` and
``fprintf`` to ``fmt::print`` if configured to do so. (By default it
converts to ``std::print``.)

Projects using this library
---------------------------

* `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform
  real-time strategy game

* `AMPL/MP <https://github.com/ampl/mp>`_:
  an open-source library for mathematical programming

* `Aseprite <https://github.com/aseprite/aseprite>`_:
  animated sprite editor & pixel art tool

* `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft
  operations suite

* `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform

* `Celestia <https://celestia.space/>`_: real-time 3D visualization of space

* `Ceph <https://ceph.com/>`_: a scalable distributed storage system

* `ccache <https://ccache.dev/>`_: a compiler cache

* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: an analytical database
  management system

* `Contour <https://github.com/contour-terminal/contour/>`_: a modern terminal emulator

* `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater
  vehicle

* `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox
  for nonlinear dynamical systems (MIT)

* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
  (Lyft)

* `FiveM <https://fivem.net/>`_: a modification framework for GTA V

* `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style
  logging library with latency in nanoseconds

* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library

* `GemRB <https://gemrb.org/>`_: a portable open-source implementation of
  Bioware’s Infinity Engine

* `Grand Mountain Adventure
  <https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
  a beautiful open-world ski & snowboarding game

* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
  Player vs Player Gaming Network with tweaks

* `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server
  engine

* `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows

* `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software

* `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node

* `libunicode <https://github.com/contour-terminal/libunicode/>`_: a modern C++17 Unicode library

* `MariaDB <https://mariadb.org/>`_: relational database management system

* `Microsoft Verona <https://github.com/microsoft/verona>`_:
  research programming language for concurrent ownership

* `MongoDB <https://mongodb.com/>`_: distributed document database

* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to
  generate randomized datasets

* `OpenSpace <https://openspaceproject.com/>`_: an open-source
  astrovisualization framework

* `PenUltima Online (POL) <https://www.polserver.com/>`_:
  an MMO server, compatible with most Ultima Online clients

* `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine
  learning library

* `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance,
  associative database

* `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library

* `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify
  navigation, and executing complex multi-line terminal command sequences

* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster
  proxy

* `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement
  for mission-critical systems written in C++

* `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client
  library

* `Salesforce Analytics Cloud
  <https://www.salesforce.com/analytics-cloud/overview/>`_:
  business intelligence software

* `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store
  that can handle 1 million transactions per second on a single server

* `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++
  framework for high-performance server applications on modern hardware

* `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library

* `Stellar <https://www.stellar.org/>`_: financial platform

* `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator

* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source
  MMORPG framework

* `🐙 userver framework <https://userver.tech/>`_: open-source asynchronous
  framework with a rich set of abstractions and database drivers

* `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows
  terminal

`More... <https://github.com/search?q=fmtlib&type=Code>`_

If you are aware of other projects using this library, please let me know
by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
`issue <https://github.com/fmtlib/fmt/issues>`_.

Motivation
----------

So why yet another formatting library?

There are plenty of methods for doing this task, from standard ones like
the printf family of function and iostreams to Boost Format and FastFormat
libraries. The reason for creating a new library is that every existing
solution that I found either had serious issues or didn't provide
all the features I needed.

printf
~~~~~~

The good thing about ``printf`` is that it is pretty fast and readily available
being a part of the C standard library. The main drawback is that it
doesn't support user-defined types. ``printf`` also has safety issues although
they are somewhat mitigated with `__attribute__ ((format (printf, ...))
<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to ``printf`` but it is not a part of C99 and may not be available on some
platforms.

iostreams
~~~~~~~~~

The main issue with iostreams is best illustrated with an example:

.. code:: c++

    std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";

which is a lot of typing compared to printf:

.. code:: c++

    printf("%.2f\n", 1.23456);

Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
don't support positional arguments by design.

The good part is that iostreams support user-defined types and are safe although
error handling is awkward.

Boost Format
~~~~~~~~~~~~

This is a very powerful library that supports both ``printf``-like format
strings and positional arguments. Its main drawback is performance. According to
various benchmarks, it is much slower than other methods considered here. Boost
Format also has excessive build times and severe code bloat issues (see
`Benchmarks`_).

FastFormat
~~~~~~~~~~

This is an interesting library that is fast, safe, and has positional arguments.
However, it has significant limitations, citing its author:

    Three features that have no hope of being accommodated within the
    current design are:

    * Leading zeros (or any other non-space padding)
    * Octal/hexadecimal encoding
    * Runtime width/alignment specification

It is also quite big and has a heavy dependency, STLSoft, which might be too
restrictive for using it in some projects.

Boost Spirit.Karma

这不是一个格式化库,但为了完整起见,我决定将其包含在此处。作为iostreams,它存在将逐字文本与参数混合的问题。该库非常快,但在整数格式上比在 Karma 自己的基准测试上编译格式字符串时慢,请参阅 _。

fmt::format_to
Converting a hundred million integers to strings per second <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>

许可证

{fmt} 在 MIT _ 下分发。

license <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>

文档许可证

文档中的 _ 部分基于 Python 中的部分。出于这个原因,文档在 Python 软件基金会许可证下分发,该许可证以 doc/python-license.txt <https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt> 形式提供。它仅适用于分发 {fmt} 的文档。

Format String Syntax <https://fmt.dev/latest/syntax.html>
string module documentation <https://docs.python.org/3/library/string.html#module-string>

维护

{fmt} 图书馆由 Victor Zverovich () 维护,并得到了许多其他人的贡献。有关某些名称,请参阅贡献者<https://github.com/fmtlib/fmt/graphs/contributors>和 _。如果你的贡献未被错误列出或提及,请告诉我们,我们会纠正它。

vitaut <https://github.com/vitaut>
Releases <https://github.com/fmtlib/fmt/releases>