For basic types and string types, the format specification is based on the format specification in Python.
The syntax of format specifications is:
fill-and-align (optional) sign (optional)#
(optional) 0
(optional) width (optional) precision (optional) L
(optional) type (optional)
The sign, #
and 0
options are only valid when an integer or floating-point presentation type is used.
fill-and-align is an optional fill character (which can be any character other than {
or }
), followed by one of the align options <
, >
, ^
.
If no fill character is specified, it defaults to the space character. For a format specification in a Unicode encoding, the fill character must correspond to a single Unicode scalar value.
The meaning of align options is as follows:
<
: Forces the formatted argument to be aligned to the start of the available space by inserting n fill characters after the formatted argument. This is the default when a non-integer non-floating-point presentation type is used.>
: Forces the formatted argument to be aligned to the end of the available space by inserting n fill characters before the formatted argument. This is the default when an integer or floating-point presentation type is used.^
: Forces the formatted argument to be centered within the available space by inserting ââ characters before and ââ characters after the formatted argument.In each case, n is the difference of the minimum field width (specified by width) and the estimated width of the formatted argument, or 0 if the difference is less than 0.
[edit] Sign, #, and 0The sign option can be one of following:
+
: Indicates that a sign should be used for both non-negative and negative numbers. The +
sign is inserted before the output value for non-negative numbers.-
: Indicates that a sign should be used for negative numbers only (this is the default behavior).Negative zero is treated as a negative number.
The sign option applies to floating-point infinity and NaN.
#include <cassert> #include <format> #include <limits> int main() { double inf = std::numeric_limits<double>::infinity(); double nan = std::numeric_limits<double>::quiet_NaN(); assert(std::format("{0:},{0:+},{0:-},{0: }", 1) == "1,+1,1, 1"); assert(std::format("{0:},{0:+},{0:-},{0: }", -1) == "-1,-1,-1,-1"); assert(std::format("{0:},{0:+},{0:-},{0: }", inf) == "inf,+inf,inf, inf"); assert(std::format("{0:},{0:+},{0:-},{0: }", nan) == "nan,+nan,nan, nan"); }
The #
option causes the alternate form to be used for the conversion.
0b
, 0
, or 0x
) into the output value after the sign character (possibly space) if there is one, or add it before the output value otherwise.g
and G
conversions, trailing zeros are not removed from the result.The 0
option pads the field with leading zeros (following any indication of sign or base) to the field width, except when applied to an infinity or NaN. If the 0
character and an align option both appear, the 0
character is ignored.
width is either a positive decimal number, or a nested replacement field ({}
or {
n}
). If present, it specifies the minimum field width.
precision is a dot (.
) followed by either a non-negative decimal number or a nested replacement field. This field indicates the precision or maximum field size. It can only be used with floating-point and string types.
If a nested replacement field is used for width or precision, and the corresponding argument is not of integral type(until C++23)standard signed or unsigned integer type(since C++23), or is negative, an exception of type std::format_error is thrown.
float pi = 3.14f; assert(std::format("{:10f}", pi) == " 3.140000"); // width = 10 assert(std::format("{:{}f}", pi, 10) == " 3.140000"); // width = 10 assert(std::format("{:.5f}", pi) == "3.14000"); // precision = 5 assert(std::format("{:.{}f}", pi, 5) == "3.14000"); // precision = 5 assert(std::format("{:10.5f}", pi) == " 3.14000"); // width = 10, precision = 5 assert(std::format("{:{}.{}f}", pi, 10, 5) == " 3.14000"); // width = 10, precision = 5 auto b1 = std::format("{:{}f}", pi, 10.0); // throws: width is not of integral type auto b2 = std::format("{:{}f}", pi, -10); // throws: width is negative auto b3 = std::format("{:.{}f}", pi, 5.0); // throws: precision is not of integral type
The width of a string is defined as the estimated number of column positions appropriate for displaying it in a terminal.
For the purpose of width computation, a string is assumed to be in an implementation-defined encoding. The method of width computation is unspecified, but for a string in a Unicode encoding, implementation should estimate the width of the string as the sum of estimated widths of the first code points in its extended grapheme clusters. The estimated width is 2 for the following code points, and is 1 otherwise:
East_Asian_Width
has value Fullwidth (F
) or Wide (W
)The L
option causes the locale-specific form to be used. This option is only valid for arithmetic types.
bool
, the locale-specific form uses the appropriate string as if obtained with std::numpunct::truename or std::numpunct::falsename.The type option determines how the data should be presented.
The available string presentation types are:
s
: Copies the string to the output.?
: Copies the escaped string (see below) to the output.The available integer presentation types for integral types other than char, wchar_t, and bool are:
b
: Binary format. Produces the output as if by calling std::to_chars(first, last, value, 2). The base prefix is 0b
.B
: same as b
, except that the base prefix is 0B
.c
: Copies the character static_cast<CharT>(value) to the output, where CharT
is the character type of the format string. Throws std::format_error if value is not in the range of representable values for CharT
.d
: Decimal format. Produces the output as if by calling std::to_chars(first, last, value).o
: Octal format. Produces the output as if by calling std::to_chars(first, last, value, 8). The base prefix is 0
if the corresponding argument value is non-zero and is empty otherwise.x
: Hex format. Produces the output as if by calling std::to_chars(first, last, value, 16). The base prefix is 0x
.X
: same as x
, except that it uses uppercase letters for digits above 9 and the base prefix is 0X
.d
.The available char and wchar_t presentation types are:
c
: Copies the character to the output.b
, B
, d
, o
, x
, X
: Uses integer presentation types with the value static_cast<unsigned char>(value) or static_cast<std::make_unsigned_t<wchar_t>>(value) respectively.?
: Copies the escaped character (see below) to the output.The available bool presentation types are:
s
: Copies textual representation (true
or false
, or the locale-specific form) to the output.b
, B
, d
, o
, x
, X
: Uses integer presentation types with the value static_cast<unsigned char>(value).The available floating-point presentation types are:
a
: If precision is specified, produces the output as if by calling std::to_chars(first, last, value, std::chars_format::hex, precision) where precision is the specified precision; otherwise, the output is produced as if by calling std::to_chars(first, last, value, std::chars_format::hex).A
: same as a
, except that it uses uppercase letters for digits above 9 and uses P
to indicate the exponent.e
: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::scientific, precision) where precision is the specified precision, or 6 if precision is not specified.E
: same as e
, except that it uses E
to indicate the exponent.f
, F
: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::fixed, precision) where precision is the specified precision, or 6 if precision is not specified.g
: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::general, precision) where precision is the specified precision, or 6 if precision is not specified.G
: same as g
, except that it uses E
to indicate the exponent.For lower-case presentation types, infinity and NaN are formatted as inf
and nan
, respectively. For upper-case presentation types, infinity and NaN are formatted as INF
and NAN
, respectively.
a
, A
std::chars_format::hex a
, A
(but std::format
does not output leading 0x
or 0X
) e
, E
std::chars_format::scientific e
, E
f
, F
std::chars_format::fixed f
, F
g
, G
std::chars_format::general g
, G
none std::chars_format::general if precision is specified, otherwise the shortest round-trip format g
if precision is specified. Otherwise there's no corresponding specifier.
The available pointer presentation types (also used for std::nullptr_t) are:
p
: If std::uintptr_t is defined, produces the output as if by calling std::to_chars(first, last, reinterpret_cast<std::uintptr_t>(value), 16) with the prefix 0x
added to the output; otherwise, the output is implementation-defined.P
: same as p
, except that it uses uppercase letters for digits above 9 and the base prefix is 0X
.A character or string can be formatted as escaped to make it more suitable for debugging or for logging.
Escaping is done as follows:
\t
line feed - new line (byte 0x0a in ASCII encoding) \n
carriage return (byte 0x0d in ASCII encoding) \r
double quote (byte 0x22 in ASCII encoding) \"
Used only if the output is a double-quoted string single quote (byte 0x27 in ASCII encoding) \'
Used only if the output is a single-quoted string backslash (byte 0x5c in ASCII encoding) \\
General_Category
has a value in the groups Separator
(Z
) or Other
(C
), orGrapheme_Extend=Yes
, or\u{hex-digit-sequence}
, where hex-digit-sequence
is the shortest hexadecimal representation of C using lower-case hexadecimal digits.
\x{hex-digit-sequence}
, where hex-digit-sequence
is the shortest hexadecimal representation of the code unit using lower-case hexadecimal digits.The escaped string representation of a string is constructed by escaping the code unit sequences in the string, as described above, and quoting the result with double quotes.
The escaped representation of a character is constructed by escaping it as described above, and quoting the result with single quotes.
Run this code
#include <print> int main() { std::println("[{:?}]", "h\tllo"); // prints: ["h\tllo"] std::println("[{:?}]", "СпаÑибо, ÐикÑÐ¾Ñ â¥!"); // prints: ["СпаÑибо, ÐикÑÐ¾Ñ â¥!"] std::println("[{:?}] [{:?}]", '\'', '"'); // prints: ['\'', '"'] // The following examples assume use of the UTF-8 encoding std::println("[{:?}]", std::string("\0 \n \t \x02 \x1b", 9)); // prints: ["\u{0} \n \t \u{2} \u{1b}"] std::println("[{:?}]", "\xc3\x28"); // invalid UTF-8 // prints: ["\x{c3}("] std::println("[{:?}]", "\u0301"); // prints: ["\u{301}"] std::println("[{:?}]", "\\\u0301"); // prints: ["\\\u{301}"] std::println("[{:?}]", "e\u0301\u0323"); // prints: ["ẹÌ"] }(since C++23) [edit] Notes
In most of the cases the syntax is similar to the old %
-formatting, with the addition of the {}
and with :
used instead of %
. For example, "%03.2f" can be translated to "{:03.2f}".
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior LWG 3721 C++20 zero is not allowed for the width fieldRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4