README.md
1<img src="https://user-images.githubusercontent.com/576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png" alt="{fmt}" width="25%"/>
2
3[](https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux)
4[](https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos)
5[](https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows)
6[](https://bugs.chromium.org/p/oss-fuzz/issues/list?\%0Acolspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\%0ASummary&q=proj%3Dfmt&can=1)
7[](https://stackoverflow.com/questions/tagged/fmt)
8[](https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt)
9
10**{fmt}** is an open-source formatting library providing a fast and safe
11alternative to C stdio and C++ iostreams.
12
13If you like this project, please consider donating to one of the funds
14that help victims of the war in Ukraine: <https://www.stopputin.net/>.
15
16[Documentation](https://fmt.dev)
17
18[Cheat Sheets](https://hackingcpp.com/cpp/libs/fmt.html)
19
20Q&A: ask questions on [StackOverflow with the tag
21fmt](https://stackoverflow.com/questions/tagged/fmt).
22
23Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
24
25# Features
26
27- Simple [format API](https://fmt.dev/latest/api.html) with positional
28 arguments for localization
29- Implementation of [C++20
30 std::format](https://en.cppreference.com/w/cpp/utility/format) and
31 [C++23 std::print](https://en.cppreference.com/w/cpp/io/print)
32- [Format string syntax](https://fmt.dev/latest/syntax.html) similar
33 to Python\'s
34 [format](https://docs.python.org/3/library/stdtypes.html#str.format)
35- Fast IEEE 754 floating-point formatter with correct rounding,
36 shortness and round-trip guarantees using the
37 [Dragonbox](https://github.com/jk-jeon/dragonbox) algorithm
38- Portable Unicode support
39- Safe [printf
40 implementation](https://fmt.dev/latest/api.html#printf-formatting)
41 including the POSIX extension for positional arguments
42- Extensibility: [support for user-defined
43 types](https://fmt.dev/latest/api.html#formatting-user-defined-types)
44- High performance: faster than common standard library
45 implementations of `(s)printf`, iostreams, `to_string` and
46 `to_chars`, see [Speed tests](#speed-tests) and [Converting a
47 hundred million integers to strings per
48 second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html)
49- Small code size both in terms of source code with the minimum
50 configuration consisting of just three files, `core.h`, `format.h`
51 and `format-inl.h`, and compiled code; see [Compile time and code
52 bloat](#compile-time-and-code-bloat)
53- Reliability: the library has an extensive set of
54 [tests](https://github.com/fmtlib/fmt/tree/master/test) and is
55 [continuously fuzzed](https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1)
56- Safety: the library is fully type-safe, errors in format strings can
57 be reported at compile time, automatic memory management prevents
58 buffer overflow errors
59- Ease of use: small self-contained code base, no external
60 dependencies, permissive MIT
61 [license](https://github.com/fmtlib/fmt/blob/master/LICENSE.rst)
62- [Portability](https://fmt.dev/latest/index.html#portability) with
63 consistent output across platforms and support for older compilers
64- Clean warning-free codebase even on high warning levels such as
65 `-Wall -Wextra -pedantic`
66- Locale independence by default
67- Optional header-only configuration enabled with the
68 `FMT_HEADER_ONLY` macro
69
70See the [documentation](https://fmt.dev) for more details.
71
72# Examples
73
74**Print to stdout** ([run](https://godbolt.org/z/Tevcjh))
75
76``` c++
77#include <fmt/core.h>
78
79int main() {
80 fmt::print("Hello, world!\n");
81}
82```
83
84**Format a string** ([run](https://godbolt.org/z/oK8h33))
85
86``` c++
87std::string s = fmt::format("The answer is {}.", 42);
88// s == "The answer is 42."
89```
90
91**Format a string using positional arguments**
92([run](https://godbolt.org/z/Yn7Txe))
93
94``` c++
95std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
96// s == "I'd rather be happy than right."
97```
98
99**Print dates and times** ([run](https://godbolt.org/z/c31ExdY3W))
100
101``` c++
102#include <fmt/chrono.h>
103
104int main() {
105 auto now = std::chrono::system_clock::now();
106 fmt::print("Date and time: {}\n", now);
107 fmt::print("Time: {:%H:%M}\n", now);
108}
109```
110
111Output:
112
113 Date and time: 2023-12-26 19:10:31.557195597
114 Time: 19:10
115
116**Print a container** ([run](https://godbolt.org/z/MxM1YqjE7))
117
118``` c++
119#include <vector>
120#include <fmt/ranges.h>
121
122int main() {
123 std::vector<int> v = {1, 2, 3};
124 fmt::print("{}\n", v);
125}
126```
127
128Output:
129
130 [1, 2, 3]
131
132**Check a format string at compile time**
133
134``` c++
135std::string s = fmt::format("{:d}", "I am not a number");
136```
137
138This gives a compile-time error in C++20 because `d` is an invalid
139format specifier for a string.
140
141**Write a file from a single thread**
142
143``` c++
144#include <fmt/os.h>
145
146int main() {
147 auto out = fmt::output_file("guide.txt");
148 out.print("Don't {}", "Panic");
149}
150```
151
152This can be [5 to 9 times faster than
153fprintf](http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html).
154
155**Print with colors and text styles**
156
157``` c++
158#include <fmt/color.h>
159
160int main() {
161 fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
162 "Hello, {}!\n", "world");
163 fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
164 fmt::emphasis::underline, "Olá, {}!\n", "Mundo");
165 fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
166 "你好{}!\n", "世界");
167}
168```
169
170Output on a modern terminal with Unicode support:
171
172
173
174# Benchmarks
175
176## Speed tests
177
178| Library | Method | Run Time, s |
179|-------------------|---------------|-------------|
180| libc | printf | 0.91 |
181| libc++ | std::ostream | 2.49 |
182| {fmt} 9.1 | fmt::print | 0.74 |
183| Boost Format 1.80 | boost::format | 6.26 |
184| Folly Format | folly::format | 1.87 |
185
186{fmt} is the fastest of the benchmarked methods, \~20% faster than
187`printf`.
188
189The above results were generated by building `tinyformat_test.cpp` on
190macOS 12.6.1 with `clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT`, and
191taking the best of three runs. In the test, the format string
192`"%0.10f:%04d:%+g:%s:%p:%c:%%\n"` or equivalent is filled 2,000,000
193times with output sent to `/dev/null`; for further details refer to the
194[source](https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc).
195
196{fmt} is up to 20-30x faster than `std::ostringstream` and `sprintf` on
197IEEE754 `float` and `double` formatting
198([dtoa-benchmark](https://github.com/fmtlib/dtoa-benchmark)) and faster
199than [double-conversion](https://github.com/google/double-conversion)
200and [ryu](https://github.com/ulfjack/ryu):
201
202[](https://fmt.dev/unknown_mac64_clang12.0.html)
203
204## Compile time and code bloat
205
206The script
207[bloat-test.py](https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py)
208from [format-benchmark](https://github.com/fmtlib/format-benchmark)
209tests compile time and code bloat for nontrivial projects. It generates
210100 translation units and uses `printf()` or its alternative five times
211in each to simulate a medium-sized project. The resulting executable
212size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), macOS
213Sierra, best of three) is shown in the following tables.
214
215**Optimized build (-O3)**
216
217| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
218|---------------|-----------------|----------------------|--------------------|
219| printf | 2.6 | 29 | 26 |
220| printf+string | 16.4 | 29 | 26 |
221| iostreams | 31.1 | 59 | 55 |
222| {fmt} | 19.0 | 37 | 34 |
223| Boost Format | 91.9 | 226 | 203 |
224| Folly Format | 115.7 | 101 | 88 |
225
226As you can see, {fmt} has 60% less overhead in terms of resulting binary
227code size compared to iostreams and comes pretty close to `printf`.
228Boost Format and Folly Format have the largest overheads.
229
230`printf+string` is the same as `printf` but with an extra `<string>`
231include to measure the overhead of the latter.
232
233**Non-optimized build**
234
235| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
236|---------------|-----------------|----------------------|--------------------|
237| printf | 2.2 | 33 | 30 |
238| printf+string | 16.0 | 33 | 30 |
239| iostreams | 28.3 | 56 | 52 |
240| {fmt} | 18.2 | 59 | 50 |
241| Boost Format | 54.1 | 365 | 303 |
242| Folly Format | 79.9 | 445 | 430 |
243
244`libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
245to compare formatting function overhead only. Boost Format is a
246header-only library so it doesn\'t provide any linkage options.
247
248## Running the tests
249
250Please refer to [Building the
251library](https://fmt.dev/latest/usage.html#building-the-library) for
252instructions on how to build the library and run the unit tests.
253
254Benchmarks reside in a separate repository,
255[format-benchmarks](https://github.com/fmtlib/format-benchmark), so to
256run the benchmarks you first need to clone this repository and generate
257Makefiles with CMake:
258
259 $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
260 $ cd format-benchmark
261 $ cmake .
262
263Then you can run the speed test:
264
265 $ make speed-test
266
267or the bloat test:
268
269 $ make bloat-test
270
271# Migrating code
272
273[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v17 (not yet
274released) provides the
275[modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
276check that is capable of converting occurrences of `printf` and
277`fprintf` to `fmt::print` if configured to do so. (By default it
278converts to `std::print`.)
279
280# Notable projects using this library
281
282- [0 A.D.](https://play0ad.com/): a free, open-source, cross-platform
283 real-time strategy game
284- [AMPL/MP](https://github.com/ampl/mp): an open-source library for
285 mathematical programming
286- [Apple's FoundationDB](https://github.com/apple/foundationdb): an open-source,
287 distributed, transactional key-value store
288- [Aseprite](https://github.com/aseprite/aseprite): animated sprite
289 editor & pixel art tool
290- [AvioBook](https://www.aviobook.aero/en): a comprehensive aircraft
291 operations suite
292- [Blizzard Battle.net](https://battle.net/): an online gaming
293 platform
294- [Celestia](https://celestia.space/): real-time 3D visualization of
295 space
296- [Ceph](https://ceph.com/): a scalable distributed storage system
297- [ccache](https://ccache.dev/): a compiler cache
298- [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
299 analytical database management system
300- [Contour](https://github.com/contour-terminal/contour/): a modern
301 terminal emulator
302- [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
303 underwater vehicle
304- [Drake](https://drake.mit.edu/): a planning, control, and analysis
305 toolbox for nonlinear dynamical systems (MIT)
306- [Envoy](https://lyft.github.io/envoy/): C++ L7 proxy and
307 communication bus (Lyft)
308- [FiveM](https://fivem.net/): a modification framework for GTA V
309- [fmtlog](https://github.com/MengRao/fmtlog): a performant
310 fmtlib-style logging library with latency in nanoseconds
311- [Folly](https://github.com/facebook/folly): Facebook open-source
312 library
313- [GemRB](https://gemrb.org/): a portable open-source implementation
314 of Bioware's Infinity Engine
315- [Grand Mountain
316 Adventure](https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/):
317 a beautiful open-world ski & snowboarding game
318- [HarpyWar/pvpgn](https://github.com/pvpgn/pvpgn-server): Player vs
319 Player Gaming Network with tweaks
320- [KBEngine](https://github.com/kbengine/kbengine): an open-source
321 MMOG server engine
322- [Keypirinha](https://keypirinha.com/): a semantic launcher for
323 Windows
324- [Kodi](https://kodi.tv/) (formerly xbmc): home theater software
325- [Knuth](https://kth.cash/): high-performance Bitcoin full-node
326- [libunicode](https://github.com/contour-terminal/libunicode/): a
327 modern C++17 Unicode library
328- [MariaDB](https://mariadb.org/): relational database management
329 system
330- [Microsoft Verona](https://github.com/microsoft/verona): research
331 programming language for concurrent ownership
332- [MongoDB](https://mongodb.com/): distributed document database
333- [MongoDB Smasher](https://github.com/duckie/mongo_smasher): a small
334 tool to generate randomized datasets
335- [OpenSpace](https://openspaceproject.com/): an open-source
336 astrovisualization framework
337- [PenUltima Online (POL)](https://www.polserver.com/): an MMO server,
338 compatible with most Ultima Online clients
339- [PyTorch](https://github.com/pytorch/pytorch): an open-source
340 machine learning library
341- [quasardb](https://www.quasardb.net/): a distributed,
342 high-performance, associative database
343- [Quill](https://github.com/odygrd/quill): asynchronous low-latency
344 logging library
345- [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
346 simplify navigation, and executing complex multi-line terminal
347 command sequences
348- [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
349 cluster proxy
350- [redpanda](https://vectorized.io/redpanda): a 10x faster Kafka®
351 replacement for mission-critical systems written in C++
352- [rpclib](http://rpclib.net/): a modern C++ msgpack-RPC server and
353 client library
354- [Salesforce Analytics
355 Cloud](https://www.salesforce.com/analytics-cloud/overview/):
356 business intelligence software
357- [Scylla](https://www.scylladb.com/): a Cassandra-compatible NoSQL
358 data store that can handle 1 million transactions per second on a
359 single server
360- [Seastar](http://www.seastar-project.org/): an advanced, open-source
361 C++ framework for high-performance server applications on modern
362 hardware
363- [spdlog](https://github.com/gabime/spdlog): super fast C++ logging
364 library
365- [Stellar](https://www.stellar.org/): financial platform
366- [Touch Surgery](https://www.touchsurgery.com/): surgery simulator
367- [TrinityCore](https://github.com/TrinityCore/TrinityCore):
368 open-source MMORPG framework
369- [ userver framework](https://userver.tech/): open-source
370 asynchronous framework with a rich set of abstractions and database
371 drivers
372- [Windows Terminal](https://github.com/microsoft/terminal): the new
373 Windows terminal
374
375[More\...](https://github.com/search?q=fmtlib&type=Code)
376
377If you are aware of other projects using this library, please let me
378know by [email](mailto:victor.zverovich@gmail.com) or by submitting an
379[issue](https://github.com/fmtlib/fmt/issues).
380
381# Motivation
382
383So why yet another formatting library?
384
385There are plenty of methods for doing this task, from standard ones like
386the printf family of function and iostreams to Boost Format and
387FastFormat libraries. The reason for creating a new library is that
388every existing solution that I found either had serious issues or
389didn\'t provide all the features I needed.
390
391## printf
392
393The good thing about `printf` is that it is pretty fast and readily
394available being a part of the C standard library. The main drawback is
395that it doesn\'t support user-defined types. `printf` also has safety
396issues although they are somewhat mitigated with [\_\_attribute\_\_
397((format (printf,
398\...))](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) in
399GCC. There is a POSIX extension that adds positional arguments required
400for
401[i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization)
402to `printf` but it is not a part of C99 and may not be available on some
403platforms.
404
405## iostreams
406
407The main issue with iostreams is best illustrated with an example:
408
409``` c++
410std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
411```
412
413which is a lot of typing compared to printf:
414
415``` c++
416printf("%.2f\n", 1.23456);
417```
418
419Matthew Wilson, the author of FastFormat, called this \"chevron hell\".
420iostreams don\'t support positional arguments by design.
421
422The good part is that iostreams support user-defined types and are safe
423although error handling is awkward.
424
425## Boost Format
426
427This is a very powerful library that supports both `printf`-like format
428strings and positional arguments. Its main drawback is performance.
429According to various benchmarks, it is much slower than other methods
430considered here. Boost Format also has excessive build times and severe
431code bloat issues (see [Benchmarks](#benchmarks)).
432
433## FastFormat
434
435This is an interesting library that is fast, safe, and has positional
436arguments. However, it has significant limitations, citing its author:
437
438> Three features that have no hope of being accommodated within the
439> current design are:
440>
441> - Leading zeros (or any other non-space padding)
442> - Octal/hexadecimal encoding
443> - Runtime width/alignment specification
444
445It is also quite big and has a heavy dependency, STLSoft, which might be
446too restrictive for using it in some projects.
447
448## Boost Spirit.Karma
449
450This is not a formatting library but I decided to include it here for
451completeness. As iostreams, it suffers from the problem of mixing
452verbatim text with arguments. The library is pretty fast, but slower on
453integer formatting than `fmt::format_to` with format string compilation
454on Karma\'s own benchmark, see [Converting a hundred million integers to
455strings per
456second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html).
457
458# License
459
460{fmt} is distributed under the MIT
461[license](https://github.com/fmtlib/fmt/blob/master/LICENSE).
462
463# Documentation License
464
465The [Format String Syntax](https://fmt.dev/latest/syntax.html) section
466in the documentation is based on the one from Python [string module
467documentation](https://docs.python.org/3/library/string.html#module-string).
468For this reason, the documentation is distributed under the Python
469Software Foundation license available in
470[doc/python-license.txt](https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt).
471It only applies if you distribute the documentation of {fmt}.
472
473# Maintainers
474
475The {fmt} library is maintained by Victor Zverovich
476([vitaut](https://github.com/vitaut)) with contributions from many other
477people. See
478[Contributors](https://github.com/fmtlib/fmt/graphs/contributors) and
479[Releases](https://github.com/fmtlib/fmt/releases) for some of the
480names. Let us know if your contribution is not listed or mentioned
481incorrectly and we\'ll make it right.
482
483# Security Policy
484
485To report a security issue, please disclose it at [security
486advisory](https://github.com/fmtlib/fmt/security/advisories/new).
487
488This project is maintained by a team of volunteers on a
489reasonable-effort basis. As such, please give us at least 90 days to
490work on a fix before public exposure.
491