{fmt} Formatting & Printing C++ Library (original) (raw)

A fast and safe alternative to C stdio and C++ iostreams

This article is based on {fmt} version 8.0.1

hello.cpp
// header-only mode not needed in compiler explorer:
// #define FMT_HEADER_ONLY

#include <fmt/core.h> 

int main () {
  fmt::print("Hello, World!\n");
}
Example Project Layout
demo/
  hello.cpp
  fmt/
    include/
      fmt/
        core.h
        …
    src/
    …
$ g++ -I fmt/include -o greet hello.cpp
$ ./greet
Hello, World!

A minimum viable setup needs the filescore.h, format.h and format-inl.hfound in fmt/include/fmt/.

demo/hello.cpp
#include <fmt/core.h> 

int main () {
  fmt::print("Hello, World!\n");
}
demo/CMakeLists.txt
cmake_minimum_required(VERSION 3.10) 
project(FmtDemo) 
add_subdirectory(fmt)
add_executable(greet hello.cpp)                                                                                                                                                                                                                                                                                   
# set to C++17 (not required)
set_property(TARGET greet PROPERTY CXX_STANDARD 17)
target_link_libraries(greet fmt::fmt)
Project Layout
demo/
  CMakeLists.txt
  hello.cpp
  fmt/
    doc/
    include/
    src/
    support/
    test/
    CMakeLists.txt
    …
$ cd demo      # project directory
$ mkdir build  # directory for build output
$ cd build
$ cmake ..     # generate build scripts
$ make Scanning dependencies of target fmt
[ 20%] Building CXX object fmt/CMakeFiles/fmt.dir/src/format.cc.o
[ 40%] Building CXX object fmt/CMakeFiles/fmt.dir/src/os.cc.o
[ 60%] Linking CXX static library libfmt.a
[ 60%] Built target fmt
Scanning dependencies of target greet
[ 80%] Building CXX object CMakeFiles/greet.dir/hello.cpp.o
[100%] Linking CXX executable greet
[100%] Built target greet
$ ./greet
Hello, World!

Build {fmt} Library (Using CMake)

see here for more details

$ cd fmt
$ mkdir build   # directory for build output
$ cd build
$ cmake ..      # generate build scripts
$ make
... build process ...
$ sudo make install
demo/hello.cpp
#include <fmt/core.h> 
int main () {
  fmt::print("Hello, World!\n");
}
demo/CMakeLists.txt
cmake_minimum_required(VERSION 3.10) 
project(FmtDemo) 
find_package(fmt)
add_executable(greet hello.cpp)                                                                                                                                                                                                                                                                                   
# set to C++17 (not required)
set_property(TARGET greet PROPERTY CXX_STANDARD 17)
target_link_libraries(greet fmt::fmt)
$ cd demo      # project directory
$ mkdir build  # directory for build output
$ cd build
$ cmake ..     # generate build scripts
$ make
... build process ...
$ ./greet
Hello, World!
hello.cpp
#include <fmt/core.h> 
int main () {
}
$ g++ -I path/to/fmt/include -o greet hello.cpp -L path/to/fmt/build -l fmt
$ ./greet
Hello, World!

1. Create {fmt} Project Using CMake

C:\users\jlp> cd fmt
C:\users\jlp> md build   # directory for build output
C:\users\jlp> cd build
C:\users\jlp> cmake ..   # generate build scripts

If Visual Studio was installed, CMake should have created a solution named FMT.sln and Project files (e.g. .vcxproj).

If you don't have Visual Studio installed on the build machine or want to target a specific Visual Studio Version, you need to specify the appropriate CMake generator and platform e.g., cmake **-G** "Visual Studio 16 2019" **-A** x64 ..

2. Add {fmt} Project To Your Solution

1. Create {fmt} Project Using CMake
$ cd fmt
$ mkdir build   # directory for build output
$ cd build
$ cmake ..      # generate build scripts

If Xcode is installed, CMake should have creaetd an .xcodeproj file.

If you don't have XCode installed on the build machine you need to specify the appropriate CMake generatorcmake **-G** "Xcode"

2. Add fmt.xcodeproj To Your Workspace

Formatting

fmt::format(string) → std::string
fmt::format(fmt-stringformat-string, args...arguments...) → std::string
fmt::format_to(@output, fmt-stringformat-string, args...arguments...)
#include <fmt/core.h>
#include <iostream>

int main () {
auto str = fmt::format("in {}s\n", 47);
std::cout << str;  // in 47s
}

Printing

fmt::print(fmt-stringformat-string, arguments...)
fmt::print(file, format-string, args...arguments...)
#include <fmt/core.h>

int main () {
fmt::print("in {}s\n", 47);  // in 47s
fmt::print(stderr, "error: {}\n", 404);  // error: 404
}
<fmt/core.h> lightweight subset of formatting API
<fmt/format.h> full API = core.h + compile-time format checks, iterators, user-def. types, …
<fmt/args.h> core.h + dynamic format arguments
<fmt/chrono.h> format.h + date and time formatting
<fmt/compile.h> format.h + format string compilation
<fmt/color.h> format.h + terminal color and text style
<fmt/os.h> format.h + file output, system APIs
<fmt/ostream.h> format.h + std::ostream support
<fmt/printf.h> format.h + printf formatting
<fmt/ranges.h> format.h + formatting support for ranges and tuples
<fmt/xchar.h> format.h + wchar_t support
#include <fmt/core.h>

int main () {
int i = 7; 
double d = 3.4;
std::string s = "text";
fmt::print("fast {} output\n", s);
fmt::print("{} times\n", 47);
fmt::print("{} of {}\n", i, 9);
fmt::print("{}|{}|{}\n", d, i, 5);        
fmt::print("escaped {{ & }}\n");
}
fast text output
47 times
7 of 9
3.4|7|5
escaped { & }
#include <vector>
#include <array>
#include <fmt/ranges.h>

int main () {
std::vector<double> v {1.2, 5.6, 7.8};
std::array<int,4> a {2, 3, 4, 5};
fmt::print("v: {}\n", v);
fmt::print("a: {}\n", a);
fmt::print("{}\n", fmt::join(v,"|"));
}
v: [1.2, 5.6, 7.8]
a: [2, 3, 4, 5]
1.2|5.6|7.8
#include <fmt/core.h>

int main () {
fmt::print("{}, {}, {}\n", 'a', 'b', 'c');
fmt::print("{0}, {1}, {2}\n", 'a', 'b', 'c');
fmt::print("{2}, {1}, {0}\n", 'a', 'b', 'c');
fmt::print("{0}{1}{0}\n", "XX", "abc");
int i = 20; 
double d = 3.4;
fmt::print("{1} to {0}\n", i, 10);
fmt::print("{0} / {0}\n", d);
}

a, b, c
a, b, c
c, b, a
XXabcXX
10 to 20
3.4 / 3.4
#include <fmt/format.h>  // literals

int main () {
int i = 2; 
double d = 4.567;
fmt::print("{x} + {x}\n", fmt::arg("x",d));
fmt::print("{pi} * {0}\n", i, fmt::arg("pi",3.14));
using namespace fmt::literals;
fmt::print("{y} | {x}\n", "x"_a=i, "y"_a=d);
}

4.567 + 4.567
3.14 * 2

4.567 | 2

{fmt} format specifications syntax overview

#include <fmt/core.h>

int main () {
int i = 18; 
fmt::print("{:+}\n", i);    // sign always
fmt::print("{:b}\n", i);    // binary
fmt::print("{:x}\n", i);    // hex
fmt::print("{:#x}\n", i);   // hex+prefix
}
#include <fmt/core.h>

int main () {

int i = 18;
fmt::print("{:6}\n", i);    // width 6
fmt::print("{:06}\n", i);   // 0-prefixed
fmt::print("\n");
fmt::print("{:>6}\n", i);   // align right
fmt::print("{:*>6}\n", i);  // align right
fmt::print("{:*^6}\n", i);  // center
fmt::print("{:*<6}\n", i);  // align left
}
    18
000018
    18
****18
**18**
18****
#include <fmt/core.h>

int main () {

double d = 34.567;
fmt::print("{:.3}\n", d);   // precision 3
fmt::print("{:+8.3}\n", d); // width 8
fmt::print("{:e}\n", d);    // exponential
fmt::print("{:.3e}\n", d);  // exp+prec
fmt::print("{:-<12}\n", ""); // line
fmt::print("{:*>+12.1e}\n", d);
}

34.6
  +34.56
3.456700e+01
3.457e+01
------------
****+3.5e+01
#include <fmt/core.h>

int main () {
fmt::print("print to stdout\n");
fmt::print(stdout, "same");
fmt::print(stderr, "warning!");
}

This can be substantially faster than C's fprintf (see here).

#include <fmt/os.h>

int main () {
fmt::ostream out = fmt::output_file("out.txt");
for (int ln = 0; ln < 4; ++ln) {
  out.print("line {}\n", ln);
}
}
out.txt
line·0\n
line·1\n
line·2\n
line·3\n
File Access Control Flags

Overwrite existing file, create file if it doesn't exist (default)

output_file("name")

output_file("name", fmt::file::**WRONLY** | fmt::file::**CREATE**)

Append to existing file, create file if it doesn't exist

output_file("name", fmt::file::**WRONLY** | fmt::file::**CREATE** | fmt::file::APPEND)

#include <cstdio>  // fopen
#include <fmt/core.h>

int main () {
std::FILE* file = std::fopen("out.txt","w");
for (int ln = 0; ln < 5; ++ln) {
  fmt::print(file, "line {}\n", ln);
}
std::fclose(file);
}
out.txt
line·0\n
line·1\n
line·2\n
line·3\n
line·4\n
Default: Compile-Time Checks

Requires a compiler with full support for consteval.

#include <fmt/core.h>

int main () {
double x = 3.456;
fmt::print("{0}\n", x);  
fmt::print("{1}\n", x);   only one arg
}
$ make
…
/home/demo/fmt/include/fmt/core.h:2432:40: error: …
2432 |  if (id >= num_args_) this->on_error("argument not found");
     |                       ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
…
make[1]: *** [CMakeFiles/Makefile2:133: CMakeFiles/errors.dir/all] Error 2                   
make: *** [Makefile:84: all] Error 2
Opt-In: Runtime Checks (Throw Exceptions)
#include <fmt/core.h>

int main () {
double x = 3.456;
fmt::print("{0}\n", x);  
fmt::print(fmt::runtime("{1}\n"), x);  
}
$ make
…
$ ./run-demo
3.46                                                                    
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted
Default: Runtime Checks (Throw Exceptions)
#include <fmt/core.h>

int main () {
double x = 3.456;
fmt::print("{0}\n", x);  
fmt::print("{1}\n", x);  
}
$ make
…
$ ./run-demo
3.46                                                                    
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted
Opt-In: Compile Time Checks
#include <fmt/format.h>

int main () {
double x = 3.456;
fmt::print(FMT_STRING("{0}\n"), x);  
fmt::print(FMT_STRING("{1}\n"), x);  
}
$ make
…
/home/demo/fmt/include/fmt/core.h:2432:40: error: …
2432 |  if (id >= num_args_) this->on_error("argument not found");
     |                       ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
…
make[1]: *** [CMakeFiles/Makefile2:133: CMakeFiles/errors.dir/all] Error 2                   
make: *** [Makefile:84: all] Error 2

{fmt} vs. C++20's std::format

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

int main () {
fmt::print("some text\n");
fmt::print("A {} B\n", "and");
fmt::print("--------------------\n");
---

std::string w = "or";
fmt::print("A {} B\n", w);
fmt::print("--------------------\n");
---

fmt::print("A{x}B{x}C\n", fmt::arg("x",w));
fmt::print("--------------------\n");
---

std::vector<char> v {'a','b','c','\0'};
fmt::print("{}\n", v.data());
}


some text
A and B

---


A or B

---

AorBorC

---


abc

{fmt} string type format specifications syntax overview

#include <fmt/core.h>

int main () {
std::string s = "Ab C";
fmt::print("--------------------\n");
---

fmt::print("|{}|\n", s);
fmt::print("--------------------\n");
---

fmt::print("|{:8}|\n", s);
fmt::print("|{:<8}|\n", s);
fmt::print("|{:^8}|\n", s);
fmt::print("|{:>8}|\n", s);
fmt::print("--------------------\n");
---

fmt::print("|{: >8}|\n", s);
fmt::print("|{:*<8}|\n", s);
fmt::print("|{:*^8}|\n", s);
fmt::print("|{:*>8}|\n", s);
}


---

|Ab C|    

---

|Ab C    |
|Ab C    |
|  Ab C  |
|    Ab C|

---

|    Ab C|
|Ab C****|
|**Ab C**|
|****Ab C|
#include <fmt/format.h>

int main () {
std::string s = "ab";
int y = 4;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", s, y);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", s, fmt::arg("w",y));
fmt::print("--------------------\n");
---

fmt::print("|{:>{w}}|\n", s, fmt::arg("w",y));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:>{w}}|\n", s, "w"_a = y);
}
#include <fmt/format.h>

int main () {
std::string s = "abcde";
fmt::print("--------------------\n");
---

fmt::print("{:.0}\n", s);
fmt::print("{:.1}\n", s);
fmt::print("{:.2}\n", s);
fmt::print("{:.3}\n", s);
fmt::print("{:.4}\n", s);
fmt::print("{:.5}\n", s);
fmt::print("{:.6}\n", s);
fmt::print("--------------------\n");
---

fmt::print("{:.{}}\n", s, 2);
fmt::print("--------------------\n");
---

fmt::print("{:.{p}}\n", s, fmt::arg("p",3));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("{:.{p}}\n", s, "p"_a=4);
}


---


a
ab
abc
abcd
abcde
abcde

---

ab

---

abc

---


abcd
#include <fmt/core.h>

int main () {
fmt::print("{}\n", "abc");
fmt::print("{}\n", 12.34);
fmt::print("--------------------\n");
---

// only accept strings:
fmt::print("{:s}\n", "abc");
fmt::print("{:s}\n", 12.34);
}

abc
12.34

---


abc
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted
#include <fmt/format.h>

int main () {
fmt::print("A {}\n", 'Z');
char c = 'B';
fmt::print("A {}\n", c);
fmt::print("A-{x}-{x}\n", fmt::arg("x",c));
}

{fmt} character type format specifications syntax overview

#include <fmt/core.h>

int main () {
char c = 'B';
fmt::print("--------------------\n");
---

fmt::print("|{:3}|\n", c);
fmt::print("|{:<3}|\n", c);  // left
fmt::print("|{:^3}|\n", c);  // centered
fmt::print("|{:>3}|\n", c);  // right
fmt::print("--------------------\n");
---

fmt::print("|{: >3}|\n", c);
fmt::print("|{:*<3}|\n", c);  // left
fmt::print("|{:*^3}|\n", c);  // centered
fmt::print("|{:*>3}|\n", c);  // right
}


---

|B  |
|B  |
| B |
|  B|

---

|  B|
|B**|
|*B*|
|**B|
#include <fmt/format.h>

int main () {
char c = 'B';
int y = 3;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", c, y);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", c, fmt::arg("w",y));
fmt::print("--------------------\n");
---

fmt::print("|{:>{w}}|\n", c, fmt::arg("w",y));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:>{w}}|\n", c, "w"_a = y);
}
#include <fmt/core.h>

int main () {
fmt::print("{}\n", 'B');
fmt::print("{}\n", 65);
fmt::print("--------------------\n");
---

// only accept strings:
fmt::print("{:c}\n", 'B');
fmt::print("{:c}\n", 65);
fmt::print("{:c}\n", "str");
}

B
65

---


B
A
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted
#include <fmt/format.h>

int main () {
int i = 18;
fmt::print("{:+06}\n", i);
fmt::print("{:*>#6x}\n", i);
}

{fmt} signed integer format specifications syntax overview

#include <fmt/core.h>

int main () {
int x = -3;
int y = 47;
fmt::print("{} {}\n", x, y);
fmt::print("{:-} {:-}\n", x, y);
fmt::print("{:+} {:+}\n", x, y);
fmt::print("{: } {: }\n", x, y);
}
#include <fmt/core.h>

int main () {
int i = -47;
fmt::print("--------------------\n");
---

fmt::print("|{:5}|\n", i);
fmt::print("|{:<5}|\n", i);  // left
fmt::print("|{:^5}|\n", i);  // centered
fmt::print("|{:>5}|\n", i);  // right
fmt::print("--------------------\n");
---

fmt::print("|{:*<5}|\n", i);  // left
fmt::print("|{:*^5}|\n", i);  // centered
fmt::print("|{:*>5}|\n", i);  // right
fmt::print("--------------------\n");
---

// sign-aware zero padding:
fmt::print("|{:05}|\n", i);
}


---

|  -47|
|-47  |
| -47 |
|  -47|

---

|-47**|
|*-47*|
|**-47|

---


|-0047|
#include <fmt/format.h>

int main () {
int i = 47;
int w = 4;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", i, w);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", i, fmt::arg("w",w));
fmt::print("--------------------\n");
---

fmt::print("|{:<{w}}|\n", i, fmt::arg("w",w));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:<{w}}|\n", i, "w"_a = w);
}
#include <fmt/format.h>

int main () {
int i = 10000000;
fmt::print("{}\n", i);
auto s = fmt::format(
  std::locale("en_US.UTF-8"),"{:L}", i);
fmt::print("{}\n", s);
fmt::print("--------------------\n");
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", i);
fmt::print("{:L}\n", i); 
}
#include <fmt/format.h>
int i = 10000000;
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", i);
fmt::print("{:L}\n", i);
#include <fmt/core.h>

int main () {
int i = -47;
fmt::print("--------------------\n");
// decimal (default):
fmt::print("{}\n", i);
fmt::print("{:d}\n", i);
fmt::print("--------------------\n");
// binary (base 2):
fmt::print("{:b}\n", i);
fmt::print("{:#b}\n", i);
fmt::print("{:#B}\n", i);
fmt::print("--------------------\n");
// octal (base 8):
fmt::print("{:o}\n", i);
fmt::print("{:#o}\n", i);
fmt::print("--------------------\n");
// hexadecimal (base 16):
fmt::print("{:x}\n", i);
fmt::print("{:#x}\n", i);
fmt::print("{:#X}\n", i);
}


-47
-47

-101111
-0b101111
-0B101111

-57
-057

-2f
-0x2f
-0X2F
#include <fmt/format.h>

int main () {
unsigned u = 18;
fmt::print("{:06}\n", u);
fmt::print("{:*>#6x}\n", u);
}

{fmt} unsigned integer format specifications syntax overview

#include <fmt/core.h>

int main () {
unsigned u =  47;
fmt::print("--------------------\n");
---

fmt::print("|{:6}|\n", u);
fmt::print("|{:<6}|\n", u);  // left
fmt::print("|{:^6}|\n", u);  // centered
fmt::print("|{:>6}|\n", u);  // right
fmt::print("--------------------\n");
---

fmt::print("|{:*<6}|\n", u);  // left
fmt::print("|{:*^6}|\n", u);  // centered
fmt::print("|{:*>6}|\n", u);  // right
fmt::print("--------------------\n");
---

// sign-aware zero padding:
fmt::print("|{:06}|\n", u);
}


---

|    47|
|47    |
|  47  |
|    47|

---

|47****|
|**47**|
|****47|

---


|000047|
#include <fmt/format.h>

int main () {
unsigned u = 47;
int w = 4;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", u, w);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", u, fmt::arg("w",w));
fmt::print("--------------------\n");
---

fmt::print("|{:<{w}}|\n", u, fmt::arg("w",w));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:<{w}}|\n", u, "w"_a = w);
}
#include <fmt/format.h>

int main () {
unsigned u = 10000000;
fmt::print("{}\n", u);
auto s = fmt::format(
  std::locale("en_US.UTF-8"),"{:L}", u);
fmt::print("{}\n", s);
fmt::print("--------------------\n");
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", u);
fmt::print("{:L}\n", u); 
}
#include <fmt/format.h>
unsigned u = 10000000;
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", u);
fmt::print("{:L}\n", u);
#include <fmt/core.h>

int main () {
unsigned u = 47;
fmt::print("--------------------\n");
// decimal (default):
fmt::print("{}\n", u);
fmt::print("{:d}\n", u);
fmt::print("--------------------\n");
// binary (base 2):
fmt::print("{:b}\n", u);
fmt::print("{:#b}\n", u);
fmt::print("{:#B}\n", u);
fmt::print("--------------------\n");
// octal (base 8):
fmt::print("{:o}\n", u);
fmt::print("{:#o}\n", u);
fmt::print("--------------------\n");
// hexadecimal (base 16):
fmt::print("{:x}\n", u);
fmt::print("{:#x}\n", u);
fmt::print("{:#X}\n", u);
}


47
47

101111
0b101111
0B101111

57
057

2f
0x2f
0X2F
#include <fmt/format.h>

int main () {
double d = 3.591;
fmt::print("{:08.4}\n", d);
fmt::print("{:*>+10.1e}\n", d);
}

{fmt} floating point number format specifications syntax overview

#include <fmt/core.h>

int main () {
double x = -3.1;
double y = 4.7;
fmt::print("{} {}\n", x, y);
fmt::print("{:-} {:-}\n", x, y);
fmt::print("{:+} {:+}\n", x, y);
fmt::print("{: } {: }\n", x, y);

---

float inf = std::numeric_limits<float>::infinity();
float nan = std::numeric_limits<float>::quiet_NaN();
fmt::print("{} {}\n", inf, nan);
fmt::print("{:+} {:+}\n", inf, nan);
fmt::print("{: } {: }\n", inf, nan);
}


-3.1 4.7
-3.1 4.7
-3.1 +4.7
-3.1  4.7

---


inf nan
+inf +nan
 inf  nan
#include <fmt/core.h>

int main () {
double x = 12.345;
fmt::print("--------------------\n");
---

fmt::print("|{:8}|\n", x);
fmt::print("|{:<8}|\n", x);
fmt::print("|{:^8}|\n", x);
fmt::print("|{:>8}|\n", x);
fmt::print("--------------------\n");
---

fmt::print("|{:*<8}|\n", x);
fmt::print("|{:*^8}|\n", x);
fmt::print("|{:*>8}|\n", x);
fmt::print("--------------------\n");
---

// sign-aware zero padding:
fmt::print("|{:08}|\n", -5.6);
}


---

|  12.345|
|12.345  |
| 12.345 |
|  12.345|

---

|12.345**|
|*12.345*|
|**12.345|

---


|-00005.6|
#include <fmt/format.h>

int main () {
double x = 1.2;
int w = 5;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", x, w);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", x, fmt::arg("w",w));
fmt::print("--------------------\n");
---

fmt::print("|{:>{w}}|\n", x, fmt::arg("w",w));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:>{w}}|\n", x, "w"_a = w);
}


---

|1.2  |

---

|1.2  |

---

|  1.2|

---

|  1.2|
#include <fmt/format.h>

int main () {
double x = 12.345;
fmt::print("--------------------\n");
// with default format
---

fmt::print("{:.0}\n", x);
fmt::print("{:.1}\n", x);
fmt::print("{:.2}\n", x);
fmt::print("{:.3}\n", x);
fmt::print("{:.4}\n", x);
fmt::print("{:.5}\n", x);
fmt::print("{:.6}\n", x);
fmt::print("{:.3}\n", 0.5);
fmt::print("{:.1}\n", 0.123);
fmt::print("--------------------\n");
// with exponential format
fmt::print("{:.0e}\n", x);
fmt::print("{:.1e}\n", x);
fmt::print("{:.2e}\n", x);
fmt::print("{:.3e}\n", x);
fmt::print("{:.4e}\n", x);
fmt::print("{:.5e}\n", x);
fmt::print("{:.6e}\n", x);
fmt::print("--------------------\n");
// width + precision
---

fmt::print("{:6.3}\n", x);  // width 6, prec 3
fmt::print("{:06.3}\n", x); // 0-prefixed
fmt::print("--------------------\n");
// with fixed format
fmt::print("{:.0f}\n", x);
fmt::print("{:.1f}\n", x);
fmt::print("{:.2f}\n", x);
fmt::print("{:.3f}\n", x);
fmt::print("{:.4f}\n", x);
fmt::print("{:.5f}\n", x);
fmt::print("{:.6f}\n", x);
fmt::print("{:.3f}\n", 0.5);
fmt::print("{:.1f}\n", 0.123);
fmt::print("--------------------\n");
// precision determined by argument:
fmt::print("{:.{}}\n", x, 2);
fmt::print("--------------------\n");
fmt::print("{:.{p}}\n", x, fmt::arg("p",3));
fmt::print("--------------------\n");
using namespace fmt::literals;
fmt::print("{:.{p}}\n", x, "p"_a=4);
}


---

10
1e+01
12
12.3
12.35
12.345
12.345
0.5
0.1

---

  12.3
0012.3
// precision determined by argument
fmt::print("{:.{}}\n", x, 2);
fmt::print("--------------------\n");
---

fmt::print("{:.{p}}\n", x, fmt::arg("p",3));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("{:.{p}}\n", x, "p"_a=4);
// with exponential format
fmt::print("{:.0e}\n", x);
fmt::print("{:.1e}\n", x);
fmt::print("{:.2e}\n", x);
fmt::print("{:.3e}\n", x);
fmt::print("{:.4e}\n", x);
fmt::print("{:.5e}\n", x);
fmt::print("{:.6e}\n", x);

1e+01
1.2e+01
1.23e+01
1.235e+01
1.2345e+01
1.23450e+01
1.234500e+01
// with fixed format
fmt::print("{:.0f}\n", x);
fmt::print("{:.1f}\n", x);
fmt::print("{:.2f}\n", x);
fmt::print("{:.3f}\n", x);
fmt::print("{:.4f}\n", x);
fmt::print("{:.5f}\n", x);
fmt::print("{:.6f}\n", x);
fmt::print("{:.3f}\n", 0.5);
fmt::print("{:.1f}\n", 0.123);

12
12.3
12.35
12.345
12.3450
12.34500
12.345000
0.500
0.1
#include <fmt/format.h>

int main () {
double x = 123.45;
fmt::print("{}\n", x);
auto s = fmt::format(
  std::locale("de_DE.UTF-8"),"{:L}", x);
fmt::print("{}\n", s);
fmt::print("--------------------\n");
std::locale::global(std::locale("de_DE.UTF-8"));
fmt::print("{}\n", x);
fmt::print("{:L}\n", x); 
}
#include <fmt/format.h>
double x = 123.45;
std::locale::global(std::locale("de_DE.UTF-8"));
fmt::print("{}\n", x);
fmt::print("{:L}\n", x);
#include <fmt/core.h>

int main () {
double x = 12.345;
fmt::print("--------------------\n");
// general (default):
fmt::print("{}\n", x);
fmt::print("{:g}\n", x);
fmt::print("{:g}\n", 100000000.);
fmt::print("{:G}\n", 100000000.);
fmt::print("--------------------\n");
// scientific notation:
fmt::print("{:e}\n", x);
fmt::print("{:E}\n", x);
fmt::print("--------------------\n");
// fixed point notation:
fmt::print("{:f}\n", x);
fmt::print("{:f}\n", 1./0);
fmt::print("{:F}\n", 1./0);
fmt::print("--------------------\n");
// force decimal point / trailing 0s:
fmt::print("{:}\n", 1.0);
fmt::print("{:#}\n", 1.0);
fmt::print("--------------------\n");
// hexadecimal (base 16):
fmt::print("{:a}\n", x);
fmt::print("{:A}\n", x);
}


12.345                
12.345                
1e+08
1E+08

1.234500e+01          
1.234500E+01          

12.345000
inf
INF

1
1.0

0x1.8b0a3d70a3d71p+3  
0X1.8B0A3D70A3D71P+3
#include <string_view>
#include <limits>
#include <fmt/core.h>

template <typename T>
void print_table (std::string_view label) {
    using lim = std::numeric_limits<T>;
    fmt::print("{0:-^40}\n{1}\n{0:-^40}\n","",label);
    fmt::print("lowest        {: .20}\n", lim::lowest());
    fmt::print("min           {: .20}\n", lim::min());
    fmt::print("max           {: .20}\n", lim::max());
    fmt::print("denorm_min    {: .20}\n", lim::denorm_min());
    fmt::print("epsilon       {: .20}\n", lim::epsilon());
    fmt::print("round_error   {: .20}\n", lim::round_error());
    fmt::print("min_exponent  {: }\n", lim::min_exponent);
    fmt::print("max_exponent  {: }\n", lim::max_exponent);
    fmt::print("quiet_NaN      {}\n", lim::quiet_NaN());
    fmt::print("digits        {: }\n", lim::digits);
    fmt::print("digits10      {: }\n", lim::digits10);
    fmt::print("+0            {: }\n", T(0));
    fmt::print("-0            {: }\n", T(-0.0));
} 

int main () {
    print_table<float>("FLOAT");
    print_table<double>("DOUBLE");
    print_table<long double>("LONG DOUBLE");
}
----------------------------------------
FLOAT
----------------------------------------
lowest        -3.4028234663852885981e+38
min            1.175494350822287508e-38
max            3.4028234663852885981e+38
denorm_min     1.4012984643248170709e-45
epsilon        1.1920928955078125e-07
round_error    0.5
min_exponent  -125
max_exponent   128
quiet_NaN      nan
digits         24
digits10       6
+0             0
-0            -0
…
#include <fmt/core.h>

int main () {
bool t = true;
fmt::print("{}\n", t);
fmt::print("{:d}\n", t);
fmt::print("{}\n", false);
}

{fmt} bool format specifications syntax overview

#include <fmt/core.h>

int main () {
bool b = true;
fmt::print("--------------------\n");
---

fmt::print("|{:6}|\n", b);
fmt::print("|{:<6}|\n", b);  // left
fmt::print("|{:^6}|\n", b);  // centered
fmt::print("|{:>6}|\n", b);  // right
fmt::print("--------------------\n");
---

fmt::print("|{: >6}|\n", b);
fmt::print("|{:*<6}|\n", b);  // left
fmt::print("|{:*^6}|\n", b);  // centered
fmt::print("|{:*>6}|\n", b);  // right
}


---

|true  |
|true  |
| true |
|  true|

---

|  true|
|true**|
|*true*|
|**true|
#include <fmt/format.h>

int main () {
bool b = true;
int y = 6;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", b, y);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", b, fmt::arg("w",y));
fmt::print("--------------------\n");
---

fmt::print("|{:>{w}}|\n", b, fmt::arg("w",y));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:>{w}}|\n", b, "w"_a = y);
}


---

|true  |

---

|true  |

---

|  true|

---


|  true|
#include <fmt/core.h>

int main () {
bool b = true;
fmt::print("--------------------\n");
---

fmt::print("{}\n", b);
fmt::print("{:s}\n", b);
fmt::print("{:d}\n", b);
fmt::print("--------------------\n");
---

fmt::print("{:b}\n", b);
fmt::print("{:#b}\n", b);
fmt::print("{:#B}\n", b);
fmt::print("--------------------\n");
---

fmt::print("{:o}\n", b);
fmt::print("{:#o}\n", b);
fmt::print("--------------------\n");
---

fmt::print("{:x}\n", b);
fmt::print("{:#x}\n", b);
fmt::print("{:#X}\n", b);
}


---

true
true
1

---

1
0b1
0B1

---

1
01

---

1
0x1
0X1
#include <fmt/format.h>

int main () {
int i = 12;
int* pi = &i;
fmt::print("{}\n", fmt::ptr(&i));
fmt::print("{}\n", fmt::ptr(pi));
}


0x7ffe55a4e7ac
0x7ffe55a4e7ac

{fmt} pointer value format specifications syntax overview

#include <fmt/format.h>

int main () {
int i = 12;
int* pi = &i;
auto const p = fmt::ptr(pi);
fmt::print("--------------------\n");
---

fmt::print("|{:18}|\n", p);
fmt::print("|{:<18}|\n", p);
fmt::print("|{:^18}|\n", p);
fmt::print("|{:>18}|\n", p);
fmt::print("--------------------\n");
---

fmt::print("|{: >18}|\n", p);
fmt::print("|{:*<18}|\n", p);
fmt::print("|{:*^18}|\n", p);
fmt::print("|{:*>18}|\n", p);
}


---

|    0x7ffe55a4e7ac|
|0x7ffe55a4e7ac    |
|  0x7ffe55a4e7ac  |
|    0x7ffe55a4e7ac|

---

|    0x7ffe55a4e7ac|
|0x7ffe55a4e7ac****|
|**0x7ffe55a4e7ac**|
|****0x7ffe55a4e7ac|
#include <fmt/format.h>

int main () {
int i = 12;
int* pi = &i;
auto const p = fmt::ptr(pi);
int const w = 18;
fmt::print("--------------------\n");
---

fmt::print("|{:{}}|\n", p, w);
fmt::print("--------------------\n");
---

fmt::print("|{:{w}}|\n", p, 
           fmt::arg("w",w));
fmt::print("--------------------\n");
---

fmt::print("|{:<{w}}|\n", p, 
           fmt::arg("w",w));
fmt::print("--------------------\n");
---

using namespace fmt::literals;
fmt::print("|{:<{w}}|\n", p, "w"_a = w);
}


---

|    0x7ffe55a4e7ac|

---


|    0x7ffe55a4e7ac|

---


|0x7ffe55a4e7ac    |

---


|0x7ffe55a4e7ac    |
#include <fmt/format.h>

int main () {
int i = 12;
fmt::print("--------------------\n");
---

fmt::print("{}\n", fmt::ptr(&i));
fmt::print("--------------------\n");
---

fmt::print("{:p}\n", fmt::ptr(&i));
fmt::print("--------------------\n");
---

// fmt::print("{:p}\n", 123); // ERROR
}


---

0x7ffe55a4e7ac

---

0x7ffe55a4e7ac

---

terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted
#include <utility>  // pair
#include <fmt/ranges.h>

int main () {
std::pair<char,int> t {'a', 2};
fmt::print("{}\n", t);
}
#include <tuple>
#include <fmt/ranges.h>

int main () {
std::tuple<char,int,double> t {'a', 2, 3.4};
fmt::print("{}\n", t);
fmt::print("{}\n", fmt::join(t,"|"));
fmt::print("{}\n", fmt::join(t,""));
}


('a', 2, 3.4)
a|2|3.4
a23.4
#include <vector>
#include <fmt/ranges.h>
#include <array>
#include <set>
#include <map>

int main () {
std::vector<int> v {2,3,4,5};
fmt::print("{}\n", v);
fmt::print("{}\n", fmt::join(v,"|"));
fmt::print("{:03}\n", fmt::join(v,"|"));
fmt::print("--------------------\n");
std::array<int,4> a {2,3,4,5};
fmt::print("{}\n", a);
fmt::print("{}\n", fmt::join(a," | ")); 
fmt::print("--------------------\n");
std::set<int> s {2,3,4,5};
fmt::print("{}\n", s);
fmt::print("{}\n", fmt::join(s,""));
fmt::print("--------------------\n");
std::map<char,int> m {{'a',2},{'b',4}};
fmt::print("{}\n", m);
fmt::print("{}\n", fmt::join(m,""));
}


[2, 3, 4, 5]
2|3|4|5
002|003|004|005
#include <array>
#include <fmt/ranges.h>

int main () {
std::array<int,4> a {2,3,4,5};
fmt::print("{}\n", a);
fmt::print("{}\n", fmt::join(a," | "));
}


[2, 3, 4, 5]
2 | 3 | 4 | 5
#include <set>
#include <fmt/ranges.h>

int main () {
std::set<int> s {2,3,4,5};
fmt::print("{}\n", s);
fmt::print("{}\n", fmt::join(s,""));
}
#include <map>
#include <fmt/ranges.h>

int main () {
std::map<char,int> m {{'a',2},{'b',4}};
fmt::print("{}\n", m);
fmt::print("{}\n", fmt::join(m,""));
}


[('a', 2),('b', 4)]
('a', 2)('b', 4)
#include <fmt/chrono.h>

int main () {
auto now = std::chrono::system_clock::now();
fmt::print("{}\n", now);
fmt::print("{:%S}\n", now);
fmt::print("{:%d/%m}\n", now);

using tp = std::chrono::time_point<
std::chrono::system_clock, std::chrono::seconds>;
fmt::print("--------------\n");
fmt::print("{:%S}\n", tp(std::chrono::seconds(47)));
using namespace std::chrono_literals;
fmt::print("{}\n", tp(32s));
fmt::print("{:%S}\n", tp(32s));
}


2021-07-04 18:03:09
09
07/04
#include <fmt/chrono.h>

int main () {
std::time_t tp = std::time(nullptr);             
auto const t = fmt::localtime(tp);
fmt::print("{}\n", t);    // no output
fmt::print("{:%D}\n", t); // %m/%d/%y
fmt::print("{:%F}\n", t); // ISO 8601
}
#include <fmt/chrono.h>

int main () {
auto const t = std::chrono::system_clock::now();
fmt::print("{}\n", t);
fmt::print("{:%Y-%m-%d}\n", t); 
fmt::print("-----------------------------------------------\n");
fmt::print("std. date + time          %c   {:%c}\n", t);
fmt::print("alt. date + time          %Ec  {:%Ec}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("ISO 8601 date             %F   {:%F}\n", t);
fmt::print("%m/%d/%y                  %D   {:%D}\n", t);
fmt::print("localized date            %x   {:%x}\n", t);
fmt::print("alt. date                 %Ex  {:%Ex}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("%H:%M:%S                  %T   {:%T}\n", t);
fmt::print("%H:%M                     %R   {:%R}\n", t);
fmt::print("localized 12-hour clock   %r   {:%r}\n", t);
fmt::print("localized time            %X   {:%X}\n", t);
fmt::print("alt. time                 %EX  {:%EX}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("year (last 2 digits)      %y   {:%y}\n", t);
fmt::print("year (4 digits)           %Y   {:%Y}\n", t);
fmt::print("century                   %C   {:%C}\n", t);
fmt::print("alt. localized repr.      %Ey  {:%Ey}\n", t);
fmt::print("alt. localized repr.      %EY  {:%EY}\n", t);
fmt::print("ISO 8601 week-based year  %G   {:%G}\n", t);
fmt::print("ISO 8601 week-based year  %g   {:%g}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("month                     %m   {:%m}\n", t);
fmt::print("locale-dep.               %Om  {:%Om}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("abbrev. name of month     %a   {:%a}\n", t);
fmt::print("full name of month        %A   {:%A}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("week (1st:Mon)  00-53     %W   {:%W}\n", t);
fmt::print("week (1st:Sun)  00-53     %U   {:%U}\n", t);
fmt::print("week (ISO 8601) 01-53     %V   {:%V}\n", t);
fmt::print("localized numerals        %OW  {:%OW}\n", t);
fmt::print("localized numerals        %OU  {:%OU}\n", t);
fmt::print("localized numerals        %OV  {:%OV}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("2-digit day of month      %d   {:%d}\n", t);
fmt::print("1-digit day of month      %e   {:%e}\n", t);   
fmt::print("localized numerals        %Od  {:%Od}\n", t);
fmt::print("localized numerals        %Oe  {:%Oe}\n", t);   
fmt::print("-----------------------------------------------\n");
fmt::print("weekday (Mon:1 - Sun:7)   %u   {:%u}\n", t);
fmt::print("weekday (Sun:0 - Sat:6)   %w   {:%w}\n", t);
fmt::print("local.  (Mon:1 - Sun:7)   %Ou  {:%Ou}\n", t);
fmt::print("local.  (Sun:0 - Sat:6)   %Ow  {:%Ow}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("abbrev. name of day       %b   {:%b}\n", t);
fmt::print("full name of day          %B   {:%B}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("day of year               %j   {:%j}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("hours (24-based)          %H   {:%H}\n", t);
fmt::print("hours (12-based)          %I   {:%I}\n", t);
fmt::print("localized numerals        %OH  {:%OH}\n", t);
fmt::print("localized numerals        %OI  {:%OI}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("minutes                   %M   {:%M}\n", t);
fmt::print("localized numerals        %OM  {:%OM}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("seconds                   %S   {:%S}\n", t);
fmt::print("localized numerals        %OS  {:%OS}\n", t);
fmt::print("-----------------------------------------------\n");
fmt::print("offset from UTC           %z   {:%z}\n", t);
fmt::print("time zone abbrev.         %Z   {:%Z}\n", t);
}
fmt::print("{}\n", t);
fmt::print("{:%Y-%m-%d}\n", t); 
fmt::print("--------------------\n");
---

fmt::print("{:%F}\n", t); // ISO 8601
fmt::print("{:%D}\n", t); // %m/%d/%y
fmt::print("--------------------\n");
---

fmt::print("{:%c}\n", t); // localized
2021-07-04 18:03:09
2021-07-04

---

2021-07-04
07/04/21

---

Sun Jul 4 18:03:09 2021
fmt::print("{:%y}\n", t); // year
fmt::print("{:%Y}\n", t); // year
fmt::print("{:%m}\n", t); // month
fmt::print("{:%b}\n", t); 
fmt::print("{:%B}\n", t);
fmt::print("{:%d}\n", t); // day of month
fmt::print("{:%a}\n", t); 
fmt::print("{:%A}\n", t);
fmt::print("{:%u}\n", t); // weekday
fmt::print("{:%w}\n", t); // weekday (US)
fmt::print("{:%j}\n", t); // day of year
fmt::print("{:%H}\n", t); // /24 hours
fmt::print("{:%M}\n", t); // minutes
fmt::print("{:%S}\n", t); // seconds
fmt::print("{:%T}\n", t); // %H:%M:%S
fmt::print("{:%I}\n", t); // /12 hours
fmt::print("{:%p}\n", t); // AM/PM

separate compilation example

i.e., types T for which anoperator **<<** (std::ostream&, _T_ const&)is defined

#include <iostream>
#include <string>

#include <fmt/ostream.h>

struct point2d {
  int x;
  int y;

  point2d(int x_, int y_): x(x_), y(y_) {}

  friend std::ostream&   operator << (std::ostream& os, point2d const& p)   {
    return os << '(' << p.x << ',' << p.y << ')';
  }
};

int main () {
std::string s = fmt::format("Position is {}", point2d{7,9});
// s = "Position is (7,9)"

std::cout << s << '\n';

fmt::print("{}\n", s);
}

Any type T can be made formattable/printable by specializing template **fmt::formatter<T>**.

If a type provides both a formatter specialization and an implicit conversion to an already formattable type, the specialization takes precedence over the conversion.

C++20'sstd::formatworks similarly, it uses specializations of std::formatter.

#include <fmt/format.h>

struct Point { double x, y; };

template <>
class fmt::formatter<Point> {
  // format specification storage
  char presentation_ = 'f';
public:
  // parse format specification and store it:
  constexpr auto   parse (format_parse_context& ctx) {     auto i = ctx.begin(), end = ctx.end();
    if (i != end && (*i == 'f' || *i == 'e')) {
      presentation_ = *i++;
    }
    if (i != end && *i != '}') {
      throw format_error(        "invalid format");
    }
    return i;  }

  // format a value using stored specification:
  template <typename FmtContext>
  constexpr auto   format (Point const& p,           FmtContext& ctx) const {     // note: we can't use ternary operator '?:' in a constexpr
    switch (presentation_) {
    default:
    // 'ctx.out()' is an output iterator
    case 'f': return format_to(ctx.out(),               "({:f}, {:f})", p.x, p.y);
    case 'e': return format_to(ctx.out(),               "({:e}, {:e})", p.x, p.y);
    }  }
};

int main () {
  Point p {1.2, 3.4};
  fmt::print("{}\n", p);
  fmt::print("{:f}\n", p);
  fmt::print("{:e}\n", p);
}
(1.2, 3.4)
(1.2, 3.4)
(1.2e+00, 3.4e+00)
#include <fmt/format.h>

enum class color {red, green, blue};

template <>
struct fmt::formatter<color> :   formatter<string_view>
{
  // use inherited 'formatter<string_view>::parse'…

  // … and only implement 'format':
  template <typename FmtContext>
  auto format (color c, FmtContext& ctx) {
    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);
  }
};

int main () {
  fmt::print("|{:>10}|\n", color::blue);
}
A custom container / range type **T** needs

that return iterators or pointers whose value type is supported by {fmt} or for which a custom {fmt}-formatter is defined.

Example 1: Wrapper around a standard container

value type of iterator is int which is printable by {fmt}

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

class IntList {
  std::vector<int> v_;
public:
  explicit 
  IntList (std::initializer_list<int> il): v_{il} {}
  [[nodiscard]] auto begin () const noexcept { return v_.begin(); }
  [[nodiscard]] auto end ()   const noexcept { return v_.end(); }
};

int main () {
  IntList l {4,8,15,16,23,42};
  fmt::print("numbers: {}\n", l);
}
numbers: [4, 8, 15, 16, 23, 24]

Example 2: Type for which begin/end return pointers

value type of iterators is double which is printable by {fmt}

#include <fmt/ranges.h>

class Point4 {
  double v_ [4];
public:
  explicit 
  Point4 (double x, double y, double z, double w): v_{x,y,z,w} {}
  [[nodiscard]] double x () const noexcept { return v_[0]; }
  [[nodiscard]] double y () const noexcept { return v_[1]; }
  [[nodiscard]] double z () const noexcept { return v_[2]; }
  [[nodiscard]] double w () const noexcept { return v_[3]; }
  [[nodiscard]] double const* begin () const noexcept { return v_; }
  [[nodiscard]] double const* end ()   const noexcept { return v_+4; }
};

int main () {
  Point4 v {4.7,2.,1.,3.2};
  fmt::print("point: {}\n", v);
}
#include <fmt/color.h>

int main () {
std::string s = "Abc\n";
fmt::print(fmt::emphasis::bold, s);                                              
fmt::print(fmt::emphasis::italic, s);                                            
fmt::print(fmt::emphasis::bold | fmt::emphasis::italic, s);
fmt::print(fg(fmt::color::red), s);                                              
fmt::print(fg(fmt::color::green), s);                                            
fmt::print(fg(fmt::color::blue), s);
fmt::print(bg(fmt::color::red), s);                                              
fmt::print(bg(fmt::color::green), s);                                            
fmt::print(bg(fmt::color::blue), s);
fmt::print(fmt::emphasis::bold | bg(fmt::color::red), s);
fmt::print(fmt::emphasis::bold | fmt::emphasis::italic | bg(fmt::color::red), s); 
}
fmt::print(fmt::emphasis::bold, s);                                              
fmt::print(fmt::emphasis::italic, s);                                            
fmt::print(fmt::emphasis::bold | fmt::emphasis::italic, s);
fmt::print(fg(fmt::color::red), s);                                              
fmt::print(fg(fmt::color::green), s);                                            
fmt::print(fg(fmt::color::blue), s);
fmt::print(bg(fmt::color::red), s);                                              
fmt::print(bg(fmt::color::green), s);                                            
fmt::print(bg(fmt::color::blue), s);
fmt::print(fmt::emphasis::bold | bg(fmt::color::red), s);
fmt::print(fmt::emphasis::bold | fmt::emphasis::italic | bg(fmt::color::red), s);

Only available for numeric types:int, float, double, bool, char, …

#include <fmt/format.h>

int main () {
int i = 10000000;
fmt::print("{}\n", i);
auto s = fmt::format(
  std::locale("en_US.UTF-8"),"{:L}", i);
fmt::print("{}\n", s);
fmt::print("--------------------\n");
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", i);
fmt::print("{:L}\n", i); 
}
#include <fmt/format.h>
int i = 10000000;
std::locale::global(std::locale("en_US.UTF-8"));
fmt::print("{}\n", i);
fmt::print("{:L}\n", i);
#include <fmt/format.h>

int main () {
double x = 123.45;
fmt::print("{}\n", x);
auto s = fmt::format(
  std::locale("de_DE.UTF-8"),"{:L}", x);
fmt::print("{}\n", s);
fmt::print("--------------------\n");
std::locale::global(std::locale("de_DE.UTF-8"));
fmt::print("{}\n", x);
fmt::print("{:L}\n", x); 
}
#include <fmt/format.h>
double x = 123.45;
std::locale::global(std::locale("de_DE.UTF-8"));
fmt::print("{}\n", x);
fmt::print("{:L}\n", x);

Does (as of {fmt} v8) not yet work for floating-point numbers and pointers.

#include <array>
#include <iostream>
#include <fmt/ranges.h>

#include <fmt/compile.h>

consteval std::array<char,5> compile_time_itoa (int value) {
  auto result = std::array<char,5>{};
  fmt::format_to(result.data(), FMT_COMPILE("{}"), value);
  return result;
}

int main () {
constexpr auto s = compile_time_itoa(37);
// s = {'3','7',' ',' ',' '}

std::cout << s.data() << '\n';
fmt::print("{}\n", s);
}

fmt::format_args and associated types can be used to pass argument lists to custom formatting functions. This helps to achieve reduced binary code sizes compared to fully parametrized functions.

fmt::**vprint(**_target_, fmt::string_view, fmt::format_args**)**

fmt::**vformat(**fmt::string_view, fmt::format_args**)**

fmt::**make_format_args(**_arguments…_**)** fmt::format_arg_store

#include <fmt/format.h>

int main () {
fmt::vprint("{}\n", fmt::make_format_args(47));
fmt::vprint("{} of {}\n", fmt::make_format_args("seven", 9));
}

Example: Formatted HTML Comment Printing

fmt::**make_args_checked(**_str_, _arguments…_**)** fmt::format_arg_store

#include <fmt/format.h>

void vcomment (fmt::string_view format, fmt::format_args args) {
  fmt::print("<-- ");
  fmt::vprint(format, args);
  fmt::print(" -->\n");
}

template <typename Str, typename... Args>
void comment (Str const& format, Args&&... args) {
  vcomment(format, fmt::make_args_checked<Args...>(format, args...));
}

int main () {
  double const d = 12.345;
  comment("{:e} and {}", d, 47);
}
<!-- 1.234500e+01 and 47 -->

**format_to**(_@target_, _format-string_, _arguments..._)

#include <fmt/format.h>

int main () 
{
double const d = 123.45678;
fmt::memory_buffer buf;
format_to(std::back_inserter(buf), "{:e}", d);

auto ptrToFormattedData  = buf.data();
auto sizeOfFormattedData = buf.size();
fmt::print("{}\n", ptrToFormattedData);
fmt::print("{}\n", sizeOfFormattedData);

auto str = to_string(buf);  // std::string str = "1.234568e+02";
fmt::print("{}\n", str);
}
#include <fmt/ranges.h>
#include <iterator>
#include <vector>

int main () 
{
double const d = 123.45678;

std::vector<char> vc;
fmt::format_to(std::back_inserter(vc), "{:e}", d);
// vc = {'1','.','2','3','4','5','6','8','e','+','0','2'}

fmt::print("{}\n", vc);
fmt::print("{}\n", vc.size());
}

**format_to_n**(_@target_, _size_, _format-string_, _arguments..._)

#include <fmt/format.h>
#include <array>

int main () 
{
double const d = 123.45678;
constexpr int N = 15;
std::array<char,N> a;  // initialized with 0s!
fmt::format_to_n(a.data(), N, "{:e}", d);
// a = {'1','.','2','3','4','5','6','8','e','+','0','2',0,0,0}

fmt::print("{}\n", a.data());
}

**formatted_size**(_format-string_, _arguments..._) size of formatted result

#include <fmt/format.h>

int main () 
{
double const d = 123.45678;
auto size = fmt::formatted_size("{:e}", d);  // size = 12

fmt::print("{}", size);
}
#include <string>
#include <memory>
#include <iostream>

#include <fmt/format.h>

// simple allocator that delegates to new/delete
template <class T> 
struct naive_allocator { 
  using value_type = T; 
  template<class U> struct rebind { using other = naive_allocator<U>; };
  T*   allocate(std::size_t n) { return new T[n]; }
  void deallocate(T* p, std::size_t) { delete[] p; } 
};         
using my_allocator = naive_allocator<char>;

---



// string that uses custom allocator
using my_string = std::basic_string<
    char, std::char_traits<char>, my_allocator>;

// format buffer that uses custom allocator
using my_buffer = fmt::basic_memory_buffer<
    char, fmt::inline_buffer_size, my_allocator>;

---



my_string vformat (
  my_allocator alloc, fmt::string_view str, fmt::format_args args) 
{
  // temp. buffer for formatting
  my_buffer buf(alloc);
  vformat_to(buf, str, args);
  // result string uses custom allocator
  return my_string(buf.data(), buf.size(), alloc);
}

template <typename... Args>
my_string format (
  my_allocator alloc, fmt::string_view str, Args const&... args) 
{
  return vformat(alloc, str, fmt::make_format_args(args...));
}

---



int main () {
  my_allocator alloc;
  auto s = format(alloc, "{} of {}", "seven", 9);
  // my_string s = "seven of 9";
  std::cout << s << '\n';
}

{fmt} – Printing & Formatting

example-based overview of formatting and printing with the {fmt} library

(click for fullscreen view)

Last updated: 2022-12-15

Found this useful? Share it: