fmt Documentation

A modern formatting library

RAW Doc

File: README.md







Ask questions at StackOverflow with the tag fmt
Support Ukraine

{fmt} is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.

Documentation

Cheat Sheets

Q&A: ask questions on StackOverflow with the tag
fmt
.

Try {fmt} in Compiler Explorer.

Features

  • Simple format API with positional
    arguments for localization
  • Implementation of C++20
    std::format
    and
    C++23 std::print
  • Format string syntax similar
    to Python's
    format
  • Fast IEEE 754 floating-point formatter with correct rounding,
    shortness and round-trip guarantees using the
    Dragonbox algorithm
  • Portable Unicode support
  • Safe printf
    implementation

    including the POSIX extension for positional arguments
  • Extensibility: support for user-defined
    types
  • High performance: faster than common standard library
    implementations of (s)printf, iostreams, to_string and
    to_chars, see Speed tests and Converting a
    hundred million integers to strings per
    second
  • Small code size both in terms of source code with the minimum
    configuration consisting of just three files, base.h, format.h
    and format-inl.h, and compiled code; see Compile time and code
    bloat
  • Reliability: the library has an extensive set of
    tests and is
    continuously fuzzed
  • Safety: the library is fully type-safe, errors in format strings can
    be reported at compile time, automatic memory management prevents
    buffer overflow errors
  • Ease of use: small self-contained code base, no external
    dependencies, permissive MIT
    license
  • Portability with
    consistent output across platforms and support for older compilers
  • Clean warning-free codebase even on high warning levels such as
    -Wall -Wextra -pedantic
  • Locale independence by default
  • Optional header-only configuration enabled with the
    FMT_HEADER_ONLY macro

See the documentation for more details.

Examples

Print to stdout (run)

c++
#include <fmt/base.h>

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

Format a string (run)

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

Format a string using positional arguments
(run)

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

Print dates and times (run)

c++
#include <fmt/chrono.h>

int main() {
  auto now = std::chrono::system_clock::now();
  fmt::print("Date and time: {}\n", now);
  fmt::print("Time: {:%H:%M}\n", now);
}

Output:

text
Date and time: 2023-12-26 19:10:31.557195597
Time: 19:10

Print a container (run)

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

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

Output:

text
[1, 2, 3]

Check a format string at compile time

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

This gives a compile-time error in C++20 because d is an invalid
format specifier for a string.

Write a file from a single thread

c++
#include <fmt/os.h>

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

This can be up to 9 times faster than fprintf.

Print with colors and text styles

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, "Olá, {}!\n", "Mundo");
  fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
             "你好{}!\n", "世界");
}

Output on a modern terminal with Unicode support:

Benchmarks

Speed tests

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} is the fastest of the benchmarked methods, ~50% faster than
printf.

The above results were generated by building tinyformat_test.cpp on
macOS 15.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.

{fmt} is up to 20-30x faster than std::ostringstream and sprintf on
IEEE754 float and double formatting
(dtoa-benchmark) and faster
than double-conversion
and ryu:

Compile time and code bloat

The script bloat-test.py from format-benchmark tests compile
time and code bloat for nontrivial projects. It generates 100 translation units
and uses printf() or its alternative five times in each to simulate a
medium-sized project. The resulting executable size and compile time (Apple
clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, best of three) is shown
in the following tables.

Optimized build (-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} is fast to compile and is comparable to printf in terms of per-call
binary size (within a rounding error on this system).

Non-optimized build

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++, and libfmt are all linked as shared libraries
to compare formatting function overhead only. Boost Format is a
header-only library so it doesn't provide any linkage options.

Running the tests

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

Benchmarks reside in a separate repository,
format-benchmarks, so to
run the benchmarks you first need to clone this repository and generate
Makefiles with CMake:

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

Then you can run the speed test:

text
$ make speed-test

or the bloat test:

text
$ make bloat-test

Migrating code

clang-tidy v18 provides the
modernize-use-std-print
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.)

Notable projects using this library

  • 0 A.D.: a free, open-source, cross-platform
    real-time strategy game
  • AMPL/MP: an open-source library for
    mathematical programming
  • Apple's FoundationDB: an open-source,
    distributed, transactional key-value store
  • Aseprite: animated sprite
    editor & pixel art tool
  • AvioBook: a comprehensive aircraft
    operations suite
  • Blizzard Battle.net: an online gaming
    platform
  • Celestia: real-time 3D visualization of
    space
  • Ceph: a scalable distributed storage system
  • ccache: a compiler cache
  • ClickHouse: an
    analytical database management system
  • ContextVision: medical imaging software
  • Contour: a modern
    terminal emulator
  • CUAUV: Cornell University's autonomous
    underwater vehicle
  • Drake: a planning, control, and analysis
    toolbox for nonlinear dynamical systems (MIT)
  • Envoy: C++ L7 proxy and
    communication bus (Lyft)
  • FiveM: a modification framework for GTA V
  • fmtlog: a performant
    fmtlib-style logging library with latency in nanoseconds
  • Folly: Facebook open-source
    library
  • GemRB: a portable open-source implementation
    of Bioware's Infinity Engine
  • Grand Mountain
    Adventure
    :
    a beautiful open-world ski & snowboarding game
  • HarpyWar/pvpgn: Player vs
    Player Gaming Network with tweaks
  • KBEngine: an open-source
    MMOG server engine
  • Keypirinha: a semantic launcher for
    Windows
  • Kodi (formerly xbmc): home theater software
  • Knuth: high-performance Bitcoin full-node
  • libunicode: a
    modern C++17 Unicode library
  • MariaDB: relational database management
    system
  • Microsoft Verona: research
    programming language for concurrent ownership
  • MongoDB: distributed document database
  • MongoDB Smasher: a small
    tool to generate randomized datasets
  • OpenSpace: an open-source
    astrovisualization framework
  • PenUltima Online (POL): an MMO server,
    compatible with most Ultima Online clients
  • PyTorch: an open-source
    machine learning library
  • quasardb: a distributed,
    high-performance, associative database
  • Quill: asynchronous low-latency
    logging library
  • QKW: generalizing aliasing to
    simplify navigation, and execute complex multi-line terminal
    command sequences
  • redis-cerberus: a Redis
    cluster proxy
  • redpanda: a 10x faster Kafka®
    replacement for mission-critical systems written in C++
  • rpclib: a modern C++ msgpack-RPC server and
    client library
  • Salesforce Analytics
    Cloud
    :
    business intelligence software
  • Scylla: a Cassandra-compatible NoSQL
    data store that can handle 1 million transactions per second on a
    single server
  • Seastar: an advanced, open-source
    C++ framework for high-performance server applications on modern
    hardware
  • spdlog: super fast C++ logging
    library
  • Stellar: financial platform
  • Touch Surgery: surgery simulator
  • TrinityCore:
    open-source MMORPG framework
  • 🐙 userver framework: open-source
    asynchronous framework with a rich set of abstractions and database
    drivers
  • Windows Terminal: the new
    Windows terminal

More...

If you are aware of other projects using this library, please let me
know by email or by submitting an
issue.

Maintainers

The {fmt} library is maintained by Victor Zverovich
(vitaut) with contributions from many other
people. See
Contributors and
Releases for some of the
names. Let us know if your contribution is not listed or mentioned
incorrectly and we'll make it right.


File: doc/api.md

API Reference

The {fmt} library API consists of the following components:

All functions and types provided by the library reside in namespace fmt
and macros have prefix FMT_.

C++ Module API

With the C++ module API, the headers listed above don't need to be included.
You can use the import fmt; statement instead. All other functionality,
listed below, remains the same.

Base API

fmt/base.h defines the base API which provides main formatting functions
for char/UTF-8 with C++20 compile-time checks. It has minimal include
dependencies for better compile times. This header is only beneficial when
using {fmt} as a library (the default) and not in the header-only mode.
It also provides formatter specializations for the following types:

  • int, long long
  • unsigned, unsigned long long
  • float, double, long double
  • bool
  • char
  • const char*, fmt::string_view
  • const void*

The following functions use format string syntax similar to that
of str.format
in Python. They take fmt and args as arguments.

fmt is a format string that contains literal text and replacement fields
surrounded by braces {}. The fields are replaced with formatted arguments
in the resulting string. fmt::format_string is a format
string which can be implicitly constructed from a string literal or a
constexpr string and is checked at compile time in C++20. To pass a runtime
format string wrap it in fmt::runtime.

args is an argument list representing objects to be formatted.

I/O errors are reported as std::system_error exceptions unless
specified otherwise.

::: print(format_string<T...>, T&&...)

::: print(FILE*, format_string<T...>, T&&...)

::: println(format_string<T...>, T&&...)

::: println(FILE*, format_string<T...>, T&&...)

::: format_to(OutputIt&&, format_string<T...>, T&&...)

::: format_to_n(OutputIt, size_t, format_string<T...>, T&&...)

::: format_to_n_result

::: formatted_size(format_string<T...>, T&&...)

Formatting User-Defined Types

The {fmt} library provides formatters for many standard C++ types.
See fmt/ranges.h for ranges and tuples including standard
containers such as std::vector, fmt/chrono.h for date and
time formatting and fmt/std.h for other standard library types.

There are two ways to make a user-defined type formattable: providing a
format_as function or specializing the formatter struct template.
Formatting of non-void pointer types is intentionally disallowed and they
cannot be made formattable via either extension API.

Use format_as if you want to make your type formattable as some other
type with the same format specifiers. The format_as function should
take an object of your type and return an object of a formattable type.
It should be defined in the same namespace as your type.
format_as cannot be used when a type also matches another formatter
specialization, such as the range formatter, because the specializations
would be ambiguous. Disable the conflicting specialization, if possible,
or provide an explicit formatter specialization instead.

Example (run):

text
#include <fmt/format.h>

namespace kevin_namespacy {

enum class film {
  house_of_cards, american_beauty, se7en = 7
};

auto format_as(film f) { return fmt::underlying(f); }

}

int main() {
  fmt::print("{}\n", kevin_namespacy::film::se7en); // Output: 7
}

Using a specialization is more complex, but gives you full control over
parsing and formatting. To use this method, specialize the formatter
struct template for your type and implement parse and format
methods.

The recommended way of defining a formatter is by reusing an existing
one via inheritance or composition. This way you can support standard
format specifiers without implementing them yourself. For example:

c++
// color.h:
#include <fmt/base.h>

enum class color {red, green, blue};

template <> struct fmt::formatter<color>: formatter<string_view> {
  // parse is inherited from formatter<string_view>.

  auto format(color c, format_context& ctx) const
    -> format_context::iterator;
};
c++
// color.cc:
#include "color.h"
#include <fmt/format.h>

auto fmt::formatter<color>::format(color c, format_context& ctx) const
    -> format_context::iterator {
  string_view name = "unknown";
  switch (c) {
  case color::red:   name = "red"; break;
  case color::green: name = "green"; break;
  case color::blue:  name = "blue"; break;
  }
  return formatter<string_view>::format(name, ctx);
}

Note that formatter<string_view>::format is defined in fmt/format.h
so it has to be included in the source file. Since parse is inherited
from formatter<string_view> it will recognize all string format
specifications, for example

c++
fmt::format("{:>10}", color::blue)

will return " blue".

In general the formatter has the following form:

text
template <> struct fmt::formatter<T> {
  // Parses format specifiers and stores them in the formatter.
  //
  // [ctx.begin(), ctx.end()) is a, possibly empty, character range that
  // contains a part of the format string starting from the format
  // specifications to be parsed, e.g. in
  //
  //   fmt::format("{:f} continued", ...);
  //
  // the range will contain "f} continued". The formatter should parse
  // specifiers until '}' or the end of the range. In this example the
  // formatter should parse the 'f' specifier and return an iterator
  // pointing to '}'.
  constexpr auto parse(format_parse_context& ctx)
    -> format_parse_context::iterator;

  // Formats value using the parsed format specification stored in this
  // formatter and writes the output to ctx.out().
  auto format(const T& value, format_context& ctx) const
    -> format_context::iterator;
};

It is recommended to at least support fill, align and width that apply
to the whole object and have the same semantics as in standard
formatters.

You can also write a formatter for a hierarchy of classes:

c++
// demo.h:
#include <type_traits>
#include <fmt/format.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of_v<A, T>, char>> :
    fmt::formatter<std::string> {
  auto format(const A& a, format_context& ctx) const {
    return formatter<std::string>::format(a.name(), ctx);
  }
};
c++
// demo.cc:
#include "demo.h"
#include <fmt/format.h>

int main() {
  B b;
  A& a = b;
  fmt::print("{}", a); // Output: B
}

Providing both a formatter specialization and a format_as overload is
disallowed.

::: basic_format_parse_context

::: context

::: format_context

Compile-Time Checks

Compile-time format string checks are enabled by default on compilers
that support C++20 consteval. On older compilers you can use the
FMT_STRING macro defined in fmt/format.h instead.

Unused arguments are allowed as in Python's str.format and ordinary functions.

See Type Erasure for an example of how to enable compile-time
checks in your own functions with fmt::format_string while avoiding template
bloat.

::: fstring

::: format_string

::: runtime(string_view)

Type Erasure

You can create your own formatting function with compile-time checks and
small binary footprint, for example (run):

c++
#include <fmt/format.h>

void vlog(const char* file, int line,
          fmt::string_view fmt, fmt::format_args args) {
  fmt::print("{}: {}: {}", file, line, fmt::vformat(fmt, args));
}

template <typename... T>
void log(const char* file, int line,
         fmt::format_string<T...> fmt, T&&... args) {
  vlog(file, line, fmt, fmt::make_format_args(args...));
}

#define MY_LOG(fmt, ...) log(__FILE__, __LINE__, fmt, __VA_ARGS__)

MY_LOG("invalid squishiness: {}", 42);

Note that vlog is not parameterized on argument types which improves
compile times and reduces binary code size compared to a fully
parameterized version.

::: make_format_args(T&...)

::: basic_format_args

::: format_args

::: basic_format_arg

Named Arguments

::: arg(const char*, const T&)

Compatibility

::: basic_string_view

::: string_view

Format API

fmt/format.h defines the full format API providing additional
formatting functions and locale support.


::: format(format_string<T...>, T&&...)

::: vformat(string_view, format_args)

::: operator""_a()

Utilities

::: ptr(T)

::: underlying(Enum)

::: to_string(const T&)

::: group_digits(T)

::: detail::buffer

::: basic_memory_buffer

System Errors

{fmt} does not use errno to communicate errors to the user, but it may
call system functions which set errno. Users should not make any
assumptions about the value of errno being preserved by library
functions.

::: system_error

::: format_system_error

Custom Allocators

The {fmt} library supports custom dynamic memory allocators. A custom
allocator class can be specified as a template argument to
fmt::basic_memory_buffer:

text
using custom_memory_buffer = 
  fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>;

It is also possible to write a formatting function that uses a custom
allocator:

text
using custom_string =
  std::basic_string<char, std::char_traits<char>, custom_allocator>;

auto vformat(custom_allocator alloc, fmt::string_view fmt,
             fmt::format_args args) -> custom_string {
  auto buf = custom_memory_buffer(alloc);
  fmt::vformat_to(std::back_inserter(buf), fmt, args);
  return custom_string(buf.data(), buf.size(), alloc);
}

template <typename ...Args>
auto format(custom_allocator alloc, fmt::string_view fmt,
            const Args& ... args) -> custom_string {
  return vformat(alloc, fmt, fmt::make_format_args(args...));
}

The allocator will be used for the output container only. Formatting
functions normally don't do any allocations for built-in and string
types except for non-default floating-point formatting that occasionally
falls back on sprintf.

Locale

All formatting is locale-independent by default. Use the 'L' format
specifier to insert the appropriate number separator characters from the
locale:

text
#include <fmt/format.h>
#include <locale>

std::locale::global(std::locale("en_US.UTF-8"));
auto s = fmt::format("{:L}", 1000000);  // s == "1,000,000"

fmt/format.h provides the following overloads of formatting functions
that take std::locale as a parameter. The locale type is a template
parameter to avoid the expensive <locale> include.

::: format(locale_ref, format_string<T...>, T&&...)

::: format_to(OutputIt, locale_ref, format_string<T...>, T&&...)

::: formatted_size(locale_ref, format_string<T...>, T&&...)

Legacy Compile-Time Checks

FMT_STRING enables compile-time checks on older compilers. It requires
C++14 or later and is a no-op in C++11.

::: FMT_STRING

To force the use of legacy compile-time checks, define the preprocessor
variable FMT_ENFORCE_COMPILE_STRING. When set, functions accepting
FMT_STRING will fail to compile with regular strings.

Range and Tuple Formatting

fmt/ranges.h provides formatting support for ranges and tuples:

text
#include <fmt/ranges.h>

fmt::print("{}", std::tuple<char, int>{'a', 42});
// Output: ('a', 42)

Using fmt::join, you can separate tuple elements with a custom separator:

text
#include <fmt/ranges.h>

auto t = std::tuple{1, 'a'};
fmt::print("{}", fmt::join(t, ", "));
// Output: 1, a

::: join(Range&&, string_view)

::: join(It, Sentinel, string_view)

::: join(std::initializer_list, string_view)

Date and Time Formatting

fmt/chrono.h provides formatters for

The format syntax is described in [Chrono Format Specifications](syntax.md#
chrono-format-specifications).

Example:

text
#include <fmt/chrono.h>

int main() {
  auto now = std::chrono::system_clock::now();

  fmt::print("The date is {:%Y-%m-%d}.\n", now);
  // Output: The date is 2020-11-07.
  // (with 2020-11-07 replaced by the current date)

  using namespace std::literals::chrono_literals;

  fmt::print("Default format: {} {}\n", 42s, 100ms);
  // Output: Default format: 42s 100ms

  fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
  // Output: strftime-like format: 03:15:30
}

::: gmtime(std::time_t)

Standard Library Types Formatting

fmt/std.h provides formatters for:

::: ptr(const std::unique_ptr<T, Deleter>&)

::: ptr(const std::shared_ptr&)

Variants

A std::variant can be formatted only if every alternative is
formattable, and requires the __cpp_lib_variant library
feature
.

Example:

text
#include <fmt/std.h>

fmt::print("{}", std::variant<char, float>('x'));
// Output: variant('x')

fmt::print("{}", std::variant<std::monostate, char>());
// Output: variant(monostate)

Bit-Fields and Packed Structs

To format a bit-field or a field of a struct with __attribute__((packed))
applied to it, you need to convert it to the underlying or compatible type via
a cast or a unary + (godbolt):

c++
struct smol {
  int bit : 1;
};

auto s = smol();
fmt::print("{}", +s.bit);

This is a known limitation of "perfect" forwarding in C++.

Compile-Time Support

fmt/compile.h provides format string compilation and compile-time
(constexpr) formatting enabled via the FMT_COMPILE macro or the _cf
user-defined literal defined in namespace fmt::literals. Format strings
marked with FMT_COMPILE or _cf are parsed, checked and converted into
efficient formatting code at compile-time. This supports arguments of built-in
and string types as well as user-defined types with format methods taking
the format context type as a template parameter in their formatter
specializations. For example (run):

text
struct point {
  double x;
  double y;
};

template <> struct fmt::formatter {
  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }

  template <typename FormatContext>
  auto format(const point& p, FormatContext& ctx) const {
    return format_to(ctx.out(), "({}, {})"_cf, p.x, p.y);
  }
};

using namespace fmt::literals;
std::string s = fmt::format("{}"_cf, point(4, 2));

Format string compilation can generate more binary code compared to the
default API and is only recommended in places where formatting is a
performance bottleneck.

The same APIs support formatting at compile time e.g. in constexpr
and consteval functions. Additionally there is an experimental
FMT_STATIC_FORMAT that allows formatting into a string of the exact
required size at compile time. Compile-time formatting works with built-in
and user-defined formatters that have constexpr format methods.
Example:

text
template <> struct fmt::formatter {
  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }

  template <typename FormatContext>
  constexpr auto format(const point& p, FormatContext& ctx) const {
    return format_to(ctx.out(), "({}, {})"_cf, p.x, p.y);
  }
};

constexpr auto s = FMT_STATIC_FORMAT("{}", point(4, 2));
const char* cstr = s.c_str(); // Points the static string "(4, 2)".

::: operator""_cf

::: FMT_COMPILE

::: FMT_STATIC_FORMAT

Terminal Colors and Text Styles

fmt/color.h provides support for terminal color and text style output.

::: print(text_style, format_string<T...>, T&&...)

::: fg(detail::color_type)

::: bg(detail::color_type)

::: styled(const T&, text_style)

System APIs

::: ostream

::: output_file(cstring_view, T...)

::: windows_error

`std::ostream` Support

fmt/ostream.h provides std::ostream support including formatting of
user-defined types that have an overloaded insertion operator
(operator<<). In order to make a type formattable via std::ostream
you should provide a formatter specialization inherited from
ostream_formatter:

text
#include <fmt/ostream.h>

struct date {
  int year, month, day;

  friend std::ostream& operator<<(std::ostream& os, const date& d) {
    return os << d.year << '-' << d.month << '-' << d.day;
  }
};

template <> struct fmt::formatter<date> : ostream_formatter {};

std::string s = fmt::format("The date is {}", date{2012, 12, 9});
// s == "The date is 2012-12-9"

::: streamed(const T&)

::: print(std::ostream&, format_string<T...>, T&&...)

Dynamic Argument Lists

The header fmt/args.h provides dynamic_format_arg_store, a builder-like API
that can be used to construct format argument lists dynamically.

::: dynamic_format_arg_store

Safe `printf`

The header fmt/printf.h provides printf-like formatting
functionality. The following functions use printf format string
syntax

with the POSIX extension for positional arguments. Unlike their standard
counterparts, the fmt functions are type-safe and throw an exception
if an argument type doesn't match its format specification.

::: printf(string_view, const T&...)

::: fprintf(std::FILE*, string_view, const T&...)

::: sprintf(string_view, const T&...)

Wide Strings

The optional header fmt/xchar.h provides support for wchar_t and
exotic character types.

::: wstring_view

::: wformat_context

::: to_wstring(const T&)

Compatibility with C++20 `std::format`

{fmt} implements nearly all of the C++20 formatting
library
with the
following differences:

  • Names are defined in the fmt namespace instead of std to avoid
    collisions with standard library implementations.

  • Width calculation doesn't use grapheme clusterization. The latter has
    been implemented in a separate branch but hasn't been integrated yet.

  • The default floating-point representation in {fmt} uses the smallest
    precision that provides round-trip guarantees similarly to other languages
    like Java and Python. std::format is currently specified in terms of
    std::to_chars which tries to generate the smallest number of characters
    (ignoring redundant digits and sign in exponent) and may produce more
    decimal digits than necessary.

Configuration Options

{fmt} provides configuration via CMake options and preprocessor macros to
enable or disable features and to optimize for binary size. For example, you
can disable OS-specific APIs defined in fmt/os.h with -DFMT_OS=OFF when
configuring CMake.

CMake Options

  • FMT_OS: When set to OFF, disables OS-specific APIs (fmt/os.h).
  • FMT_UNICODE: When set to OFF, disables Unicode support on
    Windows/MSVC. Unicode support is always enabled on other platforms.

Macros

  • FMT_HEADER_ONLY: Enables the header-only mode when defined. It is an
    alternative to using the fmt::fmt-header-only CMake target.
    Default: not defined.

  • FMT_USE_EXCEPTIONS: Disables the use of exceptions when set to 0.
    Default: 1 (0 if compiled with -fno-exceptions).

  • FMT_USE_LOCALE: When set to 0, disables locale support.
    Default: 1 (0 when FMT_OPTIMIZE_SIZE > 1).

  • FMT_CUSTOM_ASSERT_FAIL: When set to 1, allows users to provide a
    custom fmt::assert_fail function which is called on assertion failures and,
    if exceptions are disabled, on runtime errors. Default: 0.

  • FMT_BUILTIN_TYPES: When set to 0, disables built-in handling of
    arithmetic and string types other than int. This reduces library size at
    the cost of per-call overhead. Default: 1.

  • FMT_OPTIMIZE_SIZE: Controls binary size optimizations:

    • 0 - off (default)
    • 1 - disables locale support and applies some optimizations
    • 2 - disables some Unicode features, named arguments and applies more
      aggressive optimizations

Binary Size Optimization

To minimize the binary footprint of {fmt} as much as possible at the cost of
some features, you can use the following configuration:

  • CMake options:
    • FMT_OS=OFF
  • Macros:
    • FMT_BUILTIN_TYPES=0
    • FMT_OPTIMIZE_SIZE=2

File: doc/get-started.md

Get Started

Compile and run {fmt} examples online with Compiler Explorer.

{fmt} is compatible with any build system. The next section describes its usage
with CMake, while the Build Systems section covers the rest.

CMake

{fmt} provides three CMake targets: fmt::fmt for the standard compiled library,
fmt::fmt-module for the C++ module library and fmt::fmt-header-only for the
header-only library. It is recommended to use the compiled library or the module
library for improved build times.

There are three primary ways to use {fmt} with CMake:

  • FetchContent: Starting from CMake 3.11, you can use FetchContent to automatically
    download {fmt} as a dependency at configure time:

    text
    include(FetchContent)
    
      FetchContent_Declare(
        fmt
        GIT_REPOSITORY https://github.com/fmtlib/fmt
        GIT_TAG        e69e5f977d458f2650bb346dadf2ad30c5320281) # 10.2.1
      FetchContent_MakeAvailable(fmt)
    
      target_link_libraries(<your-target> fmt::fmt)
  • Installed: You can find and use an installed version of
    {fmt} in your CMakeLists.txt file as follows:

    text
    find_package(fmt)
      target_link_libraries(<your-target> fmt::fmt)
  • Embedded: You can add the {fmt} source tree to your project and include it
    in your CMakeLists.txt file:

    text
    add_subdirectory(fmt)
      target_link_libraries(<your-target> fmt::fmt)

Alternative Targets

In order to use the header-only target or the module target, simply substitute the
fmt::fmt in the above steps with fmt::fmt-header-only or fmt::fmt-module
accordingly.

Installation

Debian/Ubuntu

To install {fmt} on Debian, Ubuntu, or any other Debian-based Linux
distribution, use the following command:

text
apt install libfmt-dev

Homebrew

Install {fmt} on macOS using Homebrew:

text
brew install fmt

Conda

Install {fmt} on Linux, macOS, and Windows with Conda, using its conda-forge package:

text
conda install -c conda-forge fmt

vcpkg

Download and install {fmt} using the vcpkg package manager:

text
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install fmt

Conan

You can download and install {fmt} using the Conan package manager:

text
conan install -r conancenter --requires="fmt/[*]" --build=missing

Building from Source

CMake works by generating native makefiles or project files that can be
used in the compiler environment of your choice. The typical workflow
starts with:

text
mkdir build  # Create a directory to hold the build output.
cd build
cmake ..     # Generate native build scripts.

run in the fmt repository.

If you are on a Unix-like system, you should now see a Makefile in the
current directory. Now you can build the library by running make.

Once the library has been built you can invoke make test to run the tests.

You can control generation of the make test target with the FMT_TEST
CMake option. This can be useful if you include fmt as a subdirectory in
your project but don't want to add fmt's tests to your test target.

To build a shared library set the BUILD_SHARED_LIBS CMake variable to TRUE:

text
cmake -DBUILD_SHARED_LIBS=TRUE ..

To build a static library with position-independent code (e.g. for
linking it into another shared library such as a Python extension), set the
CMAKE_POSITION_INDEPENDENT_CODE CMake variable to TRUE:

text
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ..

After building the library you can install it on a Unix-like system by
running sudo make install.

Building the Docs

To build the documentation you need the following software installed on
your system:

First generate makefiles or project files using CMake as described in
the previous section. Then compile the doc target/project, for example:

text
make doc

This will generate the HTML documentation in doc/html.

Build Systems

build2

You can use build2, a dependency manager and a build
system, to use {fmt}.

Currently this package is available in these package repositories:

Usage:

  • build2 package name: fmt
  • Library target name: lib{fmt}

To make your build2 project depend on fmt:

  • Add one of the repositories to your configurations, or in your
    repositories.manifest, if not already there:

    text
    :
      role: prerequisite
      location: https://pkg.cppget.org/1/stable
  • Add this package as a dependency to your manifest file (example
    for version 10):

    text
    depends: fmt ~10.0.0
  • Import the target and use it as a prerequisite to your own target
    using fmt in the appropriate buildfile:

    text
    import fmt = fmt%lib{fmt}
      lib{mylib} : cxx{**} ... $fmt

Then build your project as usual with b or bdep update.

Meson

Meson WrapDB includes an fmt
package.

Usage:

  • Install the fmt subproject from the WrapDB by running:

    text
    meson wrap install fmt

    from the root of your project.

  • In your project's meson.build file, add an entry for the new subproject:

    text
    fmt = subproject('fmt')
      fmt_dep = fmt.get_variable('fmt_dep')
  • Include the new dependency object to link with fmt:

    text
    my_build_target = executable(
        'name', 'src/main.cc', dependencies: [fmt_dep])

Options:

If desired, {fmt} can be built as a static library, or as a header-only library.

For a static build, use the following subproject definition:

text
fmt = subproject('fmt', default_options: 'default_library=static')
fmt_dep = fmt.get_variable('fmt_dep')

For the header-only version, use:

text
fmt = subproject('fmt', default_options: ['header-only=true'])
fmt_dep = fmt.get_variable('fmt_header_only_dep')

Android NDK

{fmt} provides Android.mk file that can be used
to build the library with Android NDK.

Other

To use the {fmt} library with any other build system, add
include/fmt/base.h, include/fmt/format.h, include/fmt/format-inl.h,
src/format.cc and optionally other headers from a release archive or the git repository to your project, add include to include
directories and make sure src/format.cc is compiled and linked with your code.


File: doc/index.md


hide:

  • navigation
  • toc

A modern formatting library

Safety

Inspired by Python's formatting facility, {fmt} provides a safe replacement
for the printf family of functions. Errors in format strings,
which are a common source of vulnerabilities in C, are reported at
compile time. For example:

<code class="language-cpp"

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

will give a compile-time error because d is not a valid
format specifier for strings. APIs like
fmt::format
prevent buffer overflow errors via
automatic memory management.

→ Learn more

Extensibility

Formatting of most standard types, including all containers, dates,
and times is supported out-of-the-box. For example:

<code class="language-cpp"

fmt::print("{}", std::vector{1, 2, 3});

prints the vector in a JSON-like format:

[1, 2, 3]

You can make your own types formattable and even make compile-time
checks work for them.

→ Learn more

Performance

{fmt} can be anywhere from tens of percent to 20-30 times faster than
iostreams and sprintf, especially for numeric formatting.

The library minimizes dynamic memory allocations and can optionally
compile format strings to optimal code.

Unicode support

{fmt} provides portable Unicode support on major operating systems
with UTF-8 and char strings. For example:

<code class="language-cpp"

fmt::print("Слава Україні!");

will be printed correctly on Linux, macOS, and even Windows console,
irrespective of the codepages.

The default is locale-independent, but you can opt into localized
formatting and {fmt} makes it work with Unicode, addressing issues in the
standard library.

Fast compilation

The library makes extensive use of type erasure to achieve fast
compilation. fmt/base.h provides a subset of the API with
minimal include dependencies and enough functionality to replace
all uses of *printf.

Code using {fmt} is usually several times faster to compile than the
equivalent iostreams code, and while printf compiles faster
still, the gap is narrowing.


→ Learn more

Small binary footprint

Type erasure is also used to prevent template bloat, resulting in compact
per-call binary code. For example, a call to fmt::print with
a single argument is just a few
instructions
, comparable to printf despite adding
runtime safety, and much smaller than the equivalent iostreams code.

The library itself has small binary footprint and some components such as
floating-point formatting can be disabled to make it even smaller for
resource-constrained devices.

Portability

{fmt} has a small self-contained codebase with the core consisting of
just three headers and no external dependencies.

The library is highly portable and requires only a minimal subset of
C++11 features which are available in GCC 4.9, Clang 3.6, MSVC 19.10
(2017) and later. Newer compiler and standard library features are used
if available, and enable additional functionality.

Where possible, the output of formatting functions is consistent across
platforms.

Open source

{fmt} is in the top hundred open-source C++ libraries on GitHub and has
hundreds of
all-time contributors
.

The library is distributed under a permissive MIT
license and is
relied upon by many open-source projects, including Blender, PyTorch,
Apple's FoundationDB, Windows Terminal, MongoDB, and others.


File: doc/syntax.md

Format String Syntax

The formatting functions in this library — most notably
fmt::format and fmt::print — accept
format strings written in the syntax described here.

A format string is plain text with embedded replacement fields delimited by
the braces { and }. Characters outside of any replacement field are
copied to the output unchanged. To emit a literal brace, double it: {{
yields a single { in the output, and }} yields a single }.

A replacement field is described by the grammar below.


<code class="language-json"

replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}"
arg_id ::= integer | identifier
integer ::= digit+
digit ::= "0"..."9"
identifier ::= id_start id_continue*
id_start ::= "a"..."z" | "A"..."Z" | "_"
id_continue ::= id_start | digit

An arg_id selects which argument to format. It may be a non-negative
integer (positional reference) or an identifier matching the name of an
argument passed via fmt::arg (named reference). When arg_id
is omitted, arguments are consumed in left-to-right order; this automatic
indexing must be used uniformly throughout the format string — mixing
automatic and explicit numeric ids is a compile-time error (or a
format_error at runtime).

A format_spec, introduced by :, describes how the value should be
rendered. Its grammar is type-dependent; the form used by the standard
built-in types is documented in the next section.

For example:

c++
fmt::format("hello, {}", "world");
// Result: "hello, world"

fmt::format("{1}, {0}!", "world", "hello");
// Result: "hello, world!"

fmt::format("{greeting}, {name}!",
            fmt::arg("greeting", "hi"), fmt::arg("name", "fmt"));
// Result: "hi, fmt!"

A width or precision inside a format_spec may itself be written as a
nested replacement field — {} or {arg_id} — in which case it takes its
value from an integer argument at runtime. Nested fields accept only an
arg_id; they cannot themselves contain a format_spec.

Format Specification

The grammar below describes the format_spec shared by the built-in
types — integers, floating-point values, characters, strings, booleans, and
pointers — as well as by any user-defined type whose formatter reuses
fmt's parser.


<code class="language-json"

format_spec ::= [[fill]align][sign]["#"]["0"][width]["." precision]["L"][type]
fill ::= <a character other than '{' or '}'>
align ::= "<" | ">" | "^"
sign ::= "+" | "-" | " "
width ::= integer | "{" [arg_id] "}"
precision ::= integer | "{" [arg_id] "}"
type ::= "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" |
"g" | "G" | "o" | "p" | "s" | "x" | "X" | "?"

Whether a particular option is meaningful depends on the value being
formatted; options that do not apply to a value's type are diagnosed at
compile time when possible and otherwise raise a format_error.

Fill and alignment

The align field selects where padding is placed when width makes the
field wider than the value's natural rendering.

Option Effect
< Left-align; pad on the right. Default for non-numeric types.
> Right-align; pad on the left. Default for numeric types.
^ Center the value; if the padding cannot be split evenly, the extra padding character goes on the right.

The fill character is any single Unicode code point other than { or },
encoded the same way as the format string. It supplies the padding character
in place of the default space. A fill character is recognized only when it is
immediately followed by an align character — otherwise it would be
indistinguishable from an option in another position — so to use a custom
fill you must also specify an alignment.

Alignment has no observable effect when the value's natural rendering is
already at least as wide as width; the value is never truncated to fit.

c++
fmt::format("[{:<10}]", "42");   // Result: "[42        ]"
fmt::format("[{:>10}]", "42");   // Result: "[        42]"
fmt::format("[{:^10}]", "42");   // Result: "[    42    ]"
fmt::format("[{:*^10}]", "42");  // Result: "[****42****]"  - '*' as fill

Sign

The sign field controls how the sign of a numeric value is emitted. It
applies to signed integer and floating-point types only.

Option Effect
+ Always emit a sign (+ for nonnegative values, - for negative).
- Emit - only for negative values. This is the default.
space Emit a leading space for nonnegative values and - for negative ones; useful for aligning columns of signed numbers.

The sign of -0.0 is preserved in floating-point output.

c++
fmt::format("{:+d} {:+d}", 7, -7);  // Result: "+7 -7"
fmt::format("{: d} {: d}", 7, -7);  // Result: " 7 -7"

Alternate form (`#`)

The # flag selects an alternate form whose exact meaning depends on the
presentation type:

  • For integers rendered in binary, octal, or hexadecimal, it prepends the
    appropriate base prefix (0b/0B, 0, or 0x/0X). The case of the
    prefix follows the case of the type specifier — 0x for x, 0X for
    X, and so on.
  • For floating-point values, it forces the decimal point to appear in the
    output even if no fractional digits would otherwise be emitted, and
    prevents the g/G presentation types from removing trailing zeros from
    the significand.

The # flag is not accepted by non-numeric types.

Zero padding (`0`)

A 0 placed immediately before width enables sign-aware zero padding for
numeric types. Zeros are inserted between the sign (or base prefix, if any)
and the most significant digit, so that a sign or 0x prefix stays adjacent
to the digits rather than being separated by spaces. For example, {:+08d}
applied to 120 produces +0000120.

Zero padding:

  • applies only to numeric types;
  • has no effect on inf or nan;
  • is ignored when an explicit align is also present.

Width

width is a non-negative decimal integer giving the minimum number of
characters that the field should occupy. If the formatted value is shorter
than width, it is padded according to align and fill; if it is longer,
the value is written in full. width never causes the value to be
truncated.

To supply width at runtime, write the field as {} to consume the next
argument, or as {arg_id} to reference an integer argument by position or
by name.

When formatting strings, "width" is measured in display columns using a
Unicode-aware estimate (East Asian wide and fullwidth characters, plus
common emoji ranges, count as two columns; everything else counts as one).
This keeps fixed width values visually consistent in monospace renderings
that combine Latin and CJK text.

c++
fmt::format("[{:6}]", 42);
// Result: "[    42]"  - right-aligned by default
fmt::format("[{:6}]", "hi");
// Result: "[hi    ]"  - left-aligned by default
fmt::format("[{:{}}]", 42, 6);
// Result: "[    42]"  - width from an argument

Precision

precision is a non-negative decimal integer (introduced by .) whose
meaning depends on the value being formatted. As with width, it may be
supplied as a nested replacement field for runtime evaluation.

Type Meaning of .precision
e, E, f, F Digits emitted after the decimal point.
g, G Total number of significant digits.
a, A Digits after the decimal point in the hexadecimal significand. If omitted, just enough digits are emitted to round-trip the value exactly.
Strings (s, ?, or default) Upper bound on the number of code points copied from the value.

A precision is not accepted for integer, character, boolean, or pointer
types. When a precision limits the number of characters taken from a C
string, the string must still be null-terminated.

c++
fmt::format("{:.2f}", 3.14159);        // Result: "3.14"
fmt::format("{:.3g}", 3.14159);        // Result: "3.14"
fmt::format("{:.4}", "hello, world");  // Result: "hell"
fmt::format("{:.{}f}", 3.14159, 4);
// Result: "3.1416"  - precision from an argument

Locale (`L`)

The L flag selects locale-sensitive formatting for numeric types. The
formatter inspects the C++ locale supplied to the formatting function (or
the global locale, if none was passed) and inserts the locale's digit
grouping characters and — for floating-point values — its decimal point.
The flag has no effect on non-numeric types.

c++
auto loc = std::locale("en_US.UTF-8");
fmt::format(loc, "{:L}", 1234567890);     // Result: "1,234,567,890"
fmt::format(loc, "{:.2Lf}", 1234567.89);  // Result: "1,234,567.89"

Presentation type

The type field chooses the representation for the value. Specifiers are
grouped below by the value categories they apply to.

Integers, booleans, and characters:

Type Effect
b Base 2. The # flag adds a 0b prefix.
B Base 2. The # flag adds a 0B prefix.
c Render the integer as the character with that code point. Not allowed for bool.
d Base 10. The default for integer types.
o Base 8.
x Base 16, lower-case digits. The # flag adds a 0x prefix.
X Base 16, upper-case digits. The # flag adds a 0X prefix.
none Same as d for integers, c for characters, and the textual form (true/false) for bool.
c++
fmt::format("{:d} {:#x} {:#o} {:#b}", 42, 42, 42, 42);
// Result: "42 0x2a 052 0b101010"

fmt::format("{:#06x}", 0xfe);  // # adds the prefix, 06 zero-pads to width 6
// Result: "0x00fe"

Floating-point values:

Type Effect
a Hexadecimal-significand form (e.g. 0x1.8p+1). Lower-case digits and a lower-case p for the binary exponent. The 0x prefix is always emitted, matching printf's %a. The # flag forces a decimal point (e.g. 0x1.p+1).
A Same as a, but upper-case throughout.
e Scientific notation with a lower-case e for the decimal exponent.
E Scientific notation with an upper-case E.
f Fixed-point notation.
F Same as f, but renders nan as NAN and inf as INF.
g General form: scientific notation when the exponent would be less than −4 or not less than the precision, otherwise fixed-point; trailing zeros are removed from the fractional part unless # is set. A precision of 0 is interpreted as 1.
G Same as g, but uses E for the exponent and upper-case INF/NAN.
none Shortest round-trip representation: the formatted value, when parsed back into the same floating-point type, reproduces the input bit for bit.

Strings and characters:

Type Effect
s Plain string output. Default for string types and for bool (which is rendered as true or false).
c Character output. Default for character types. Not allowed for bool.
? Debug output: the value is wrapped in single quotes (characters) or double quotes (strings), and non-printable, non-ASCII, and special characters are escaped using C-style escape sequences such as \n, \t, \", and \u{...}.
none Same as s for strings and bool, and as c for characters.
c++
fmt::format("{}",   "tab\there");  // Result contains a literal tab character.
fmt::format("{:?}", "tab\there");  // Result: "\"tab\\there\""

Pointers:

Type Effect
p Hexadecimal address prefixed by 0x. Default for pointer types.
none Same as p.

A C string (char* or const char*) accepts both the string presentation
types and p, so the same value can be formatted as either text or an
address.

Chrono Format Specification

The format specification for chrono duration and time point types as well
as std::tm has the following syntax:


<code class="language-json"

chrono_format_spec ::= [[fill]align][width]["." precision][chrono_specs]
chrono_specs ::= conversion_spec |
chrono_specs (conversion_spec | literal_char)
conversion_spec ::= "%" [padding_modifier] [locale_modifier] chrono_type
literal_char ::= <a character other than '{', '}' or '%'>
padding_modifier ::= "-" | "_" | "0"
locale_modifier ::= "E" | "O"
chrono_type ::= "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" |
"F" | "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" |
"n" | "p" | "q" | "Q" | "r" | "R" | "S" | "t" | "T" |
"u" | "U" | "V" | "w" | "W" | "x" | "X" | "y" | "Y" |
"z" | "Z" | "%"

Literal chars are copied unchanged to the output. Precision is valid only
for std::chrono::duration types with a floating-point representation type.

The available presentation types (chrono_type) are:

Type Meaning
'a' The abbreviated weekday name, e.g. "Sat". If the value does not contain a
text
valid weekday, an exception of type `format_error` is thrown. |

| 'A' | The full weekday name, e.g. "Saturday". If the value does not contain a
valid weekday, an exception of type format_error is thrown. |
| 'b' | The abbreviated month name, e.g. "Nov". If the value does not contain a
valid month, an exception of type format_error is thrown. |
| 'B' | The full month name, e.g. "November". If the value does not contain a valid
month, an exception of type format_error is thrown. |
| 'c' | The date and time representation, e.g. "Sat Nov 12 22:04:00 1955". The
modified command %Ec produces the locale's alternate date and
time representation. |
| 'C' | The year divided by 100 using floored division, e.g. "19". If the result
is a single decimal digit, it is prefixed with 0. The modified command
%EC produces the locale's alternative representation of the
century. |
| 'd' | The day of month as a decimal number. If the result is a single decimal
digit, it is prefixed with 0. The modified command %Od
produces the locale's alternative representation. |
| 'D' | Equivalent to %m/%d/%y, e.g. "11/12/55". |
| 'e' | The day of month as a decimal number. If the result is a single decimal
digit, it is prefixed with a space. The modified command %Oe
produces the locale's alternative representation. |
| 'F' | Equivalent to %Y-%m-%d, e.g. "1955-11-12". |
| 'g' | The last two decimal digits of the ISO week-based year. If the result is a
single digit it is prefixed by 0. |
| 'G' | The ISO week-based year as a decimal number. If the result is less than
four digits it is left-padded with 0 to four digits. |
| 'h' | Equivalent to %b, e.g. "Nov". |
| 'H' | The hour (24-hour clock) as a decimal number. If the result is a single
digit, it is prefixed with 0. The modified command %OH
produces the locale's alternative representation. |
| 'I' | The hour (12-hour clock) as a decimal number. If the result is a single
digit, it is prefixed with 0. The modified command %OI
produces the locale's alternative representation. |
| 'j' | If the type being formatted is a specialization of duration, the decimal
number of days without padding. Otherwise, the day of the year as a decimal
number. Jan 1 is 001. If the result is less than three digits, it is
left-padded with 0 to three digits. |
| 'm' | The month as a decimal number. Jan is 01. If the result is a single digit,
it is prefixed with 0. The modified command %Om produces the
locale's alternative representation. |
| 'M' | The minute as a decimal number. If the result is a single digit, it
is prefixed with 0. The modified command %OM produces the
locale's alternative representation. |
| 'n' | A new-line character. |
| 'p' | The AM/PM designations associated with a 12-hour clock. |
| 'q' | The duration's unit suffix. |
| 'Q' | The duration's numeric value (as if extracted via .count()). |
| 'r' | The 12-hour clock time, e.g. "10:04:00 PM". |
| 'R' | Equivalent to %H:%M, e.g. "22:04". |
| 'S' | Seconds as a decimal number. If the number of seconds is less than 10, the
result is prefixed with 0. If the precision of the input cannot be exactly
represented with seconds, then the format is a decimal floating-point number
with a fixed format and a precision matching that of the precision of the
input (or to a microseconds precision if the conversion to floating-point
decimal seconds cannot be made within 18 fractional digits). The modified
command %OS produces the locale's alternative representation. |
| 't' | A horizontal-tab character. |
| 'T' | Equivalent to %H:%M:%S. |
| 'u' | The ISO weekday as a decimal number (1-7), where Monday is 1. The modified
command %Ou produces the locale's alternative representation. |
| 'U' | The week number of the year as a decimal number. The first Sunday of the
year is the first day of week 01. Days of the same year prior to that are
in week 00. If the result is a single digit, it is prefixed with 0.
The modified command %OU produces the locale's alternative
representation. |
| 'V' | The ISO week-based week number as a decimal number. If the result is a
single digit, it is prefixed with 0. The modified command %OV
produces the locale's alternative representation. |
| 'w' | The weekday as a decimal number (0-6), where Sunday is 0. The modified
command %Ow produces the locale's alternative representation. |
| 'W' | The week number of the year as a decimal number. The first Monday of the
year is the first day of week 01. Days of the same year prior to that are
in week 00. If the result is a single digit, it is prefixed with 0.
The modified command %OW produces the locale's alternative
representation. |
| 'x' | The date representation, e.g. "11/12/55". The modified command
%Ex produces the locale's alternate date representation. |
| 'X' | The time representation, e.g. "10:04:00". The modified command
%EX produces the locale's alternate time representation. |
| 'y' | The last two decimal digits of the year. If the result is a single digit
it is prefixed by 0. The modified command %Oy produces the
locale's alternative representation. The modified command %Ey
produces the locale's alternative representation of offset from
%EC (year only). |
| 'Y' | The year as a decimal number. If the result is less than four digits it is
left-padded with 0 to four digits. The modified command %EY
produces the locale's alternative full year representation. |
| 'z' | The offset from UTC in the ISO 8601:2004 format. For example -0430 refers
to 4 hours 30 minutes behind UTC. If the offset is zero, +0000 is used.
The modified commands %Ez and %Oz insert a
: between the hours and minutes: -04:30. If the offset
information is not available, an exception of type
format_error is thrown. |
| 'Z' | The time zone abbreviation. If the time zone abbreviation is not available,
an exception of type format_error is thrown. |
| '%' | A % character. |

Specifiers that have a calendaric component such as 'd' (the day of month)
are valid only for std::tm and time points but not durations.

The available padding modifiers (padding_modifier) are:

Type Meaning
'_' Pad a numeric result with spaces.
'-' Do not pad a numeric result string.
'0' Pad a numeric result string with zeros.

These modifiers are only supported for the 'H', 'I', 'M', 'S', 'U',
'V', 'W', 'Y', 'd', 'j' and 'm' presentation types.

Example:

c++
#include <fmt/chrono.h>

auto t = std::tm();
t.tm_year = 2010 - 1900;
t.tm_mon = 7;
t.tm_mday = 4;
t.tm_hour = 12;
t.tm_min = 15;
t.tm_sec = 58;
fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
// Prints: 2010-08-04 12:15:58

Range Format Specification

The format specification for range types has the following syntax:

<code class="language-json"

range_format_spec ::= ["n"][range_type][":" range_underlying_spec]

The 'n' option formats the range without the opening and closing brackets.

The available presentation types for range_type are:

Type Meaning
none Default format.
's' String format. The range is formatted as a string.
'?⁠s' Debug format. The range is formatted as an escaped string.

If range_type is 's' or '?s', the range element type must be a character
type. The 'n' option and range_underlying_spec are mutually exclusive with
's' and '?s'.

The range_underlying_spec is parsed based on the formatter of the range's
element type.

By default, a range of characters or strings is printed escaped and quoted.
But if any range_underlying_spec is provided (even if it is empty), then the
characters or strings are printed according to the provided specification.

Examples:

c++
fmt::print("{}", std::vector{10, 20, 30});
// Output: [10, 20, 30]
fmt::print("{::#x}", std::vector{10, 20, 30});
// Output: [0xa, 0x14, 0x1e]
fmt::print("{}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: ['h', 'e', 'l', 'l', 'o']
fmt::print("{:n}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: 'h', 'e', 'l', 'l', 'o'
fmt::print("{:s}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: "hello"
fmt::print("{:?s}", std::vector{'h', 'e', 'l', 'l', 'o', '\n'});
// Output: "hello\n"
fmt::print("{::}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: [h, e, l, l, o]
fmt::print("{::d}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: [104, 101, 108, 108, 111]
fmt::print("{:n:f}", std::array{std::numbers::pi, std::numbers::e});
// Output: 3.141593, 2.718282

A Combined Example

The example below ties together several elements introduced above — nested
replacement fields, fill characters, and centering — to draw a fixed-width
box around a message:

c++
fmt::print(
    "┌{0:─^{2}}┐\n"
    "│{1: ^{2}}│\n"
    "└{0:─^{2}}┘\n", "", "Hello, world!", 20);

Output:

text
┌────────────────────┐
│   Hello, world!    │
└────────────────────┘