/std_format_cheatsheet

Cheatsheet for the c++20 format library

std::format cheatsheet

std::format cheatsheet

If you like this content, you can contact me or follow me on Twitter 👍

Tweet for help

Introduction

What is std::format?

The std::format is a text formatting library since C++20, which offers a safe and extensible alternative to the printf family of functions. It is intended to complement the existing C++ I/O streams library and reuse some of its infrastructure such as overloaded insertion operators for user-defined types.

Formatting functions

format

cppreference

format_to

cppreference

format_to_n

cppreference

formatted_size

cppreference

Table of Contents

Requirement

#include <format>
compiler support Text Formatting (C++20) status
Visual Studio VS 2019 16.10 / cl 19.29 completed
GCC 13.1 completed
clang 14 completed

Source: cppreference

Currently ways to formatting in C++

printf() function inherited from C

#include <cstdio>	// C library for Input/Output operations
const int answer { 42 };

printf( "The answer is %d ", answer );

C++ I/O streams

const int answer { 42 };

std::cout << "The answer is " << answer << "\n";

Boost Format

const int answer { 42 };

std::cout << boost::format( "The answer is %") % answer;

www.boost.org

Fast Format

const int answer { 42 };

ff::fmtll( std::cout,  "The answer is {0}", answer );

www.fastformat.org

std::format in <format>

const int answer { 42 };

std::cout << std::format( "The answer is {}", answer );

Placeholder

The {} indicates a replacement field like % in printf.

Brace-delimited replacement fields

std::cout << std::format( "The answer is {}", 42 );

Writes the following output:

The answer is 42

Positional arguments

std::cout << std::format( "I'd rather be {1} than {0}", "right", "happy" );

curly braces in output

std::cout << std::format( "The answer is {{ }}", 42 );

Format specifiers

Placeholder can contains a format specifiers. It starts with a colon: {[index]:[format specifiers]}

[[fill]align][sign][#][0][width][.precision][type]

[width]

minimum desired field width

std::cout << std::format( "{:5}", 42 );
std::cout << std::format( "{:{}}", 42, 5 );

[[fill]align]

Specifies optional characters and aligment

Aligment

  • < left

  • > right

  • ^ center

std::cout << std::format( "{:<20}", "left");
std::cout << std::format( "{:>20}", "right");
std::cout << std::format( "{:^20}", "centered");

Fill and aligment

std::cout << std::format( "{:-^20}", "centered");

[sign]

  • - sign only for negative numbers (default)

  • + sign for negative and positive numbers

  • scape display minus sign for negative numbers, a space for positive numbers

std::cout << std::format( "{:<5}", 42 );
std::cout << std::format( "{:<+5}", 42 );
std::cout << std::format( "{:< 5}", 42 );
std::cout << std::format( "{:< 5}", -42 );

[#]

  • enabled alternative formatting rules

  • integral types

    • Hexadecimal format: inserts 0x or 0X at font
    • Binray format: inserts 0b or 0B at font
    • Octal format: inserts 0
  • floating-points types

    • always show decimal separator, even without following digits
std::cout << std::format( "{:15d}", 42 );
std::cout << std::format( "{:15b}", 42 );
std::cout << std::format( "{:#15b}", 42 );
std::cout << std::format( "{:15X}", 42 );
std::cout << std::format( "{:#15X}", 42 );

[type]

integer types

floating-points types

booleans

characters

strings

pointers

[.precision]

only for floating-points types and strings types

const double pi { 3.1415 };
const int precision { 2 };
const int width { 15 };
std::cout << std::format( "{:15.2f}", pi );
std::cout << std::format( "{:15.{}f}", pi, precision );
std::cout << std::format( "{:{}.{}f}", pi, width, precision );
std::cout << std::format( "{0:{1}.{2}f}", pi, width, precision );

Localization

std::locale is supported in std::format

Note: Use :L to enable locale specific formatting for an argument.

#include <locale>
std::cout << std::format( locale( "en_US.UTF-8" ), "{:L}", 1024 );
std::cout << std::format( locale( "zh_CN.UTF-8" ), "{:L}", 1024 );
std::cout << std::format( locale( "de_DE.UTF-8" ), "{:L}", 1024 );

formating std::chrono

#include <chrono>

Example 1

std::cout << std::format( "{:%d.%m.%Y}.", std::chrono::system_clock::now() ) << "\n";

Example 2

void print_happy_birthday( const std::string_view& name, const std::chrono::year_month_day& birthday )
{
	std::cout << std::format( "{0}'s birthday is {1:%Y-%m-%d}.", name, birthday ) << "\n";
}
using namespace std::chrono;
year_month_day birthday { 1976y / February / 1 };
std::string name { "Max Mustermann" };

print_happy_birthday( name , birthday );

formating std::complex

#include <complex>
std::complex<double> c { 4.0, 8.0 };
std::cout << std::format( "{}", c);

formating custom types

Seperate parsing anf formatting in extension API

Need to provide a specialization of std::formater<> and imlpement

  • formatter<>::parse()
  • formatter<>::fomrat()

Example Person

class Person
{
public:
	Person() = delete;
	Person( unsigned long long id, const std::string& firstName, const std::string& lastName ) noexcept
		: _id( id ), _firstName( firstName ), _lastName( lastName ) {}

	auto getId() const noexcept -> unsigned long long
	{
		return _id;
	}
	auto getFirstName() const noexcept -> const std::string&
	{
		return _firstName;
	}
	auto getLastName() const noexcept -> const std::string&
	{
		return _lastName;
	}

private:
	unsigned long long _id;
	std::string _firstName;
	std::string _lastName;
};
template<>
class std::formatter<Person>
{
public:
	constexpr auto parse( auto& context )
	{
	
	}
	
	auto format( const Person& person, auto& context )
	{
	
	}
};