The {fmt} Library
The standard options for formatting strings in C++ are, frankly, annoying and cumbersome. Yesterday, while using C++ stream format manipulators, I realized that someone must have come up with a clean solution to this common annoyance by now. So, I did a Google search for "C++ python-style string formatting" and eventually found the fmt library (formerly known as cppformat). Fmt is a lightweight library that allows you to use a syntax that is very similar to the string formatting mini-language supported by Python's str.format() function and the Rust language's string formatting syntax.
Here's a simple example:
[cpp] #includeusing namespace fmt::literals; // only needed if you are going to use the _a or _format literals.
int main()
{
const int x = 67;
const int y = 45;
const float f = 32.6;
fmt::print("Hello World! This is the number {}\n", x);
fmt::print("This is padded with zeros {:04d} and this is not padded {}\n", x, y);
fmt::print("Floating point formatting with {1} decimal places {0:0.3f}\n", f, 3);
fmt::print(stderr, "{:>25}\n", "Right-aligned"); // printed to the standard error stream
fmt::print("{:>25}\n", "Also right-aligned");
fmt::print("{:^25}\n", "Centered");
// using the _format literal
std::string message = "This is a {0} string that was {0} with {1}.\n"_format("formatted", "literals");
fmt::print(message);
auto first_name = "Nathaniel";
auto last_name = "Stickley";
auto domain_name = "caltech.edu";
// using the _a literal to name the parameters.
fmt::print("My name is {first} {last} ({last}@{domain}).\n",
"first"_a=first_name,
"last"_a=last_name,
"domain"_a=domain_name);
// print color (this is an experimental feature)
fmt::print_colored(fmt::RED, "Error: "); // this prints to the terminal in red.
fmt::print("an error message");
return 0;
}
[/cpp]
The output of the program looks like this:
Hello World! This is the number 67
This is padded with zeros 0067 and this is not padded 45
Floating point formatting with 3 decimal places 32.600
Right-aligned
Also right-aligned
Centered
This is a formatted string that was formatted with literals.
My name is Nathaniel Stickley (Stickley@caltech.edu).
Error: an error message
Many more usage examples are given in the documentation here and here.
To download the library and install it, I suggest ignoring the instructions on the fmt website and GitHub (if you are running Linux, anyway). Here's a summary of what I did:
[bash] $ git clone https://github.com/fmtlib/fmt.git$ sudo mkdir /usr/local/include/fmt
$ sudo cp fmt/fmt/format.* /usr/local/include/fmt/
[/bash]
Then, when you compile a program that uses fmt, compile using the header-only library option, by setting FMT_HEADER_ONLY
. I suggest this because you may encounter bugs if you try to compile the shared (dynamic) library. For example, to compile the program above, do this:
[/bash]
Alternatively, you can put format.h and format.cc in your source directory and #include "format.h"
instead of fmt/format.h
. Then compile with:
[/bash]
Of course, you may encounter no problems at all when using the shared library, so it's still worth a try.