std::format

std::format#

Note

We will look at the C++20 way to format output. An alternate way to set precision and how wide an output field is can be found in the iomanip library

Important

You need to use C++20 for this method. This means using GCC >= 13, and adding the -std=c++20 flag when compiling.

std::format takes a string as the first argument with {} embedded as placeholders and then inserts the remaining arguments into the string, in order, in the {}.

We’ll look at its basic usage.

Basic output#

Here’s a simple example:

Listing 23 format_simple.cpp#
#include <iostream>
#include <format>
#include <string>

int main() {

    int x{10};
    double y{1.23e-4};
    std::string a{"test"};

    std::string formatted = std::format("x = {}; y = {}; a = {}\n", x, y, a);

    std::cout << formatted;

}

When run, this outputs x = 10; y = 0.000123; a = test with a new line (since we added the \n;

Each variable / object we specify as an argument after the first argument is inserted in order into the {} in the format string.

Note

You need to include the <format> header to use std::format.

Tip

We don’t need to make an intermediate string, we could just send the output of std::format to the output stream, std::cout directly like:

std::cout << std::format("x = {}; y = {}; a = {}\n", x, y, a);

If we include more arguments after the format string than there are {}, the extra arguments are just ignored:

Listing 24 format_too_many.cpp#
#include <iostream>
#include <format>
#include <string>

int main() {

    int x{10};
    double y{1.23e-4};
    double z{-10.5};
    std::string a{"test"};

    std::cout << std::format("x = {}; y = {}; a = {}\n", x, y, a, z);


}

If we don’t provide enough arguments, then the code will not compile.

Formatting#

Within the {} we can specify the formatting using format specifiers.

Note

These specifiers are the same as used in the Python programming language. A detailed overview is given in the python docs for the format specification mini-language

The basic form is {:specifier}, where the specifier has fields giving:

  • Filling and alignment

  • sign, 0 padding

  • width

  • precision

  • type

We;ll look at the basic cases that we usually care about—mainly specifying the width of the output, the precision, and the type.

Here’s an example:

Listing 25 format_specifiers.cpp#
#include <iostream>
#include <format>
#include <string>

int main() {

    int x{10};
    double y{1.23e-6};
    double z{10.25};
    std::string a{"test"};

    std::cout << std::format("(x = {:03d}; y = {:8.3g}; z = {:4.1f} a = {:10})\n", x, y, z, a);

}

this gives:

(x = 010; y = 1.23e-06; z = 10.2 a = test      )

Let’s see what these do:

  • for the int x{10}, we use the specifier 03d.

    This uses 3 characters for the width of the field, puts 0 s in any empty field, and the d specifies that it is an integer.

  • for the double y{1.23e-6}, we use the specifier 8.3g.

    This says to use 8 characters for the width with 3 digits of precision after the decimal, and the g asks it to use scientific notation for large exponents and fixed formatting for small exponents.

  • for the double z{10.25}, we use the specifier 4.1f.

    This says to use 4 characters for the width with 1 digit of precision after the decimal, and the f requires it to use fixed-format (never switch to scientific notation).

  • for the std::string a{"test"}, we use the specifier 10.

    This says to use 10 characters for the width. Since our string is only 4 characters long, we see that it adds spaces to the end.

Tip

Specifying the width is a great way to output data in columns, which will make it easy to plot. We’ll see this later.

std::print#

In C++23, things become even simpler, with the addition of std::print and std::println. For example, we can do:

Listing 26 println.cpp#
#include <print>

int main() {

    std::println("Hello, World");

}

and compile this as:

g++ -std=c++23 -o println println.cpp

The difference between std::print and std::println is that std::println adds a newline to the end.

Note

This requires GCC >= 14