xref: /aosp_15_r20/external/fmtlib/doc/syntax.md (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
1# Format String Syntax
2
3Formatting functions such as [`fmt::format`](api.md#format) and [`fmt::print`](
4api.md#print) use the same format string syntax described in this section.
5
6Format strings contain "replacement fields" surrounded by curly braces `{}`.
7Anything that is not contained in braces is considered literal text, which is
8copied unchanged to the output. If you need to include a brace character in
9the literal text, it can be escaped by doubling: `{{` and `}}`.
10
11The grammar for a replacement field is as follows:
12
13<a id="replacement-field"></a>
14<pre><code class="language-json"
15>replacement_field ::= "{" [arg_id] [":" (<a href="#format-spec"
16  >format_spec</a> | <a href="#chrono-format-spec">chrono_format_spec</a>)] "}"
17arg_id            ::= integer | identifier
18integer           ::= digit+
19digit             ::= "0"..."9"
20identifier        ::= id_start id_continue*
21id_start          ::= "a"..."z" | "A"..."Z" | "_"
22id_continue       ::= id_start | digit</code>
23</pre>
24
25In less formal terms, the replacement field can start with an *arg_id* that
26specifies the argument whose value is to be formatted and inserted into the
27output instead of the replacement field. The *arg_id* is optionally followed
28by a *format_spec*, which is preceded by a colon `':'`. These specify a
29non-default format for the replacement value.
30
31See also the [Format Specification
32Mini-Language](#format-specification-mini-language) section.
33
34If the numerical arg_ids in a format string are 0, 1, 2, ... in sequence,
35they can all be omitted (not just some) and the numbers 0, 1, 2, ... will be
36automatically inserted in that order.
37
38Named arguments can be referred to by their names or indices.
39
40Some simple format string examples:
41
42```c++
43"First, thou shalt count to {0}" // References the first argument
44"Bring me a {}"                  // Implicitly references the first argument
45"From {} to {}"                  // Same as "From {0} to {1}"
46```
47
48The *format_spec* field contains a specification of how the value should
49be presented, including such details as field width, alignment, padding,
50decimal precision and so on. Each value type can define its own
51"formatting mini-language" or interpretation of the *format_spec*.
52
53Most built-in types support a common formatting mini-language, which is
54described in the next section.
55
56A *format_spec* field can also include nested replacement fields in
57certain positions within it. These nested replacement fields can contain
58only an argument id; format specifications are not allowed. This allows
59the formatting of a value to be dynamically specified.
60
61See the [Format Examples](#format-examples) section for some examples.
62
63## Format Specification Mini-Language
64
65"Format specifications" are used within replacement fields contained within a
66format string to define how individual values are presented. Each formattable
67type may define how the format specification is to be interpreted.
68
69Most built-in types implement the following options for format
70specifications, although some of the formatting options are only
71supported by the numeric types.
72
73The general form of a *standard format specifier* is:
74
75<a id="format-spec"></a>
76<pre><code class="language-json"
77>format_spec ::= [[fill]align][sign]["#"]["0"][width]["." precision]["L"][type]
78fill        ::= &lt;a character other than '{' or '}'>
79align       ::= "<" | ">" | "^"
80sign        ::= "+" | "-" | " "
81width       ::= <a href="#replacement-field">integer</a> | "{" [<a
82  href="#replacement-field">arg_id</a>] "}"
83precision   ::= <a href="#replacement-field">integer</a> | "{" [<a
84  href="#replacement-field">arg_id</a>] "}"
85type        ::= "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" |
86                "g" | "G" | "o" | "p" | "s" | "x" | "X" | "?"</code>
87</pre>
88
89The *fill* character can be any Unicode code point other than `'{'` or `'}'`.
90The presence of a fill character is signaled by the character following it,
91which must be one of the alignment options. If the second character of
92*format_spec* is not a valid alignment option, then it is assumed that both
93the fill character and the alignment option are absent.
94
95The meaning of the various alignment options is as follows:
96
97<table>
98<tr>
99  <th>Option</th>
100  <th>Meaning</th>
101</tr>
102<tr>
103  <td><code>'<'</code></td>
104  <td>
105    Forces the field to be left-aligned within the available space (this is the
106    default for most objects).
107  </td>
108</tr>
109<tr>
110  <td><code>'>'</code></td>
111  <td>
112    Forces the field to be right-aligned within the available space (this is
113    the default for numbers).
114  </td>
115</tr>
116<tr>
117  <td><code>'^'</code></td>
118  <td>Forces the field to be centered within the available space.</td>
119</tr>
120</table>
121
122Note that unless a minimum field width is defined, the field width will
123always be the same size as the data to fill it, so that the alignment
124option has no meaning in this case.
125
126The *sign* option is only valid for floating point and signed integer types,
127and can be one of the following:
128
129<table>
130<tr>
131  <th>Option</th>
132  <th>Meaning</th>
133</tr>
134<tr>
135  <td><code>'+'</code></td>
136  <td>
137    Indicates that a sign should be used for both nonnegative as well as
138    negative numbers.
139  </td>
140</tr>
141<tr>
142  <td><code>'-'</code></td>
143  <td>
144    Indicates that a sign should be used only for negative numbers (this is the
145    default behavior).
146  </td>
147</tr>
148<tr>
149  <td>space</td>
150  <td>
151    Indicates that a leading space should be used on nonnegative numbers, and a
152    minus sign on negative numbers.
153  </td>
154</tr>
155</table>
156
157The `'#'` option causes the "alternate form" to be used for the
158conversion. The alternate form is defined differently for different
159types. This option is only valid for integer and floating-point types.
160For integers, when binary, octal, or hexadecimal output is used, this
161option adds the prefix respective `"0b"` (`"0B"`), `"0"`, or `"0x"`
162(`"0X"`) to the output value. Whether the prefix is lower-case or
163upper-case is determined by the case of the type specifier, for example,
164the prefix `"0x"` is used for the type `'x'` and `"0X"` is used for
165`'X'`. For floating-point numbers the alternate form causes the result
166of the conversion to always contain a decimal-point character, even if
167no digits follow it. Normally, a decimal-point character appears in the
168result of these conversions only if a digit follows it. In addition, for
169`'g'` and `'G'` conversions, trailing zeros are not removed from the
170result.
171
172*width* is a decimal integer defining the minimum field width. If not
173specified, then the field width will be determined by the content.
174
175Preceding the *width* field by a zero (`'0'`) character enables
176sign-aware zero-padding for numeric types. It forces the padding to be
177placed after the sign or base (if any) but before the digits. This is
178used for printing fields in the form "+000000120". This option is only
179valid for numeric types and it has no effect on formatting of infinity
180and NaN. This option is ignored when any alignment specifier is present.
181
182The *precision* is a decimal number indicating how many digits should be
183displayed after the decimal point for a floating-point value formatted
184with `'f'` and `'F'`, or before and after the decimal point for a
185floating-point value formatted with `'g'` or `'G'`. For non-number types
186the field indicates the maximum field size - in other words, how many
187characters will be used from the field content. The *precision* is not
188allowed for integer, character, Boolean, and pointer values. Note that a
189C string must be null-terminated even if precision is specified.
190
191The `'L'` option uses the current locale setting to insert the appropriate
192number separator characters. This option is only valid for numeric types.
193
194Finally, the *type* determines how the data should be presented.
195
196The available string presentation types are:
197
198<table>
199<tr>
200  <th>Type</th>
201  <th>Meaning</th>
202</tr>
203<tr>
204  <td><code>'s'</code></td>
205  <td>
206    String format. This is the default type for strings and may be omitted.
207  </td>
208</tr>
209<tr>
210  <td><code>'?'</code></td>
211  <td>Debug format. The string is quoted and special characters escaped.</td>
212</tr>
213<tr>
214  <td>none</td>
215  <td>The same as <code>'s'</code>.</td>
216</tr>
217</table>
218
219The available character presentation types are:
220
221<table>
222<tr>
223  <th>Type</th>
224  <th>Meaning</th>
225</tr>
226<tr>
227  <td><code>'c'</code></td>
228  <td>
229    Character format. This is the default type for characters and may be
230    omitted.
231  </td>
232</tr>
233<tr>
234  <td><code>'?'</code></td>
235  <td>Debug format. The character is quoted and special characters escaped.</td>
236</tr>
237<tr>
238  <td>none</td>
239  <td>The same as <code>'c'</code>.</td>
240</tr>
241</table>
242
243The available integer presentation types are:
244
245<table>
246<tr>
247  <th>Type</th>
248  <th>Meaning</th>
249</tr>
250<tr>
251  <td><code>'b'</code></td>
252  <td>
253    Binary format. Outputs the number in base 2. Using the <code>'#'</code>
254    option with this type adds the prefix <code>"0b"</code> to the output value.
255  </td>
256</tr>
257<tr>
258  <td><code>'B'</code></td>
259  <td>
260    Binary format. Outputs the number in base 2. Using the <code>'#'</code>
261    option with this type adds the prefix <code>"0B"</code> to the output value.
262  </td>
263</tr>
264<tr>
265  <td><code>'c'</code></td>
266  <td>Character format. Outputs the number as a character.</td>
267</tr>
268<tr>
269  <td><code>'d'</code></td>
270  <td>Decimal integer. Outputs the number in base 10.</td>
271</tr>
272<tr>
273  <td><code>'o'</code></td>
274  <td>Octal format. Outputs the number in base 8.</td>
275</tr>
276<tr>
277  <td><code>'x'</code></td>
278  <td>
279    Hex format. Outputs the number in base 16, using lower-case letters for the
280    digits above 9. Using the <code>'#'</code> option with this type adds the
281    prefix <code>"0x"</code> to the output value.
282  </td>
283</tr>
284<tr>
285  <td><code>'X'</code></td>
286  <td>
287    Hex format. Outputs the number in base 16, using upper-case letters for the
288    digits above 9. Using the <code>'#'</code> option with this type adds the
289    prefix <code>"0X"</code> to the output value.
290  </td>
291</tr>
292<tr>
293  <td>none</td>
294  <td>The same as <code>'d'</code>.</td>
295</tr>
296</table>
297
298Integer presentation types can also be used with character and Boolean values
299with the only exception that `'c'` cannot be used with `bool`. Boolean values
300are formatted using textual representation, either `true` or `false`, if the
301presentation type is not specified.
302
303The available presentation types for floating-point values are:
304
305<table>
306<tr>
307  <th>Type</th>
308  <th>Meaning</th>
309</tr>
310<tr>
311  <td><code>'a'</code></td>
312  <td>
313    Hexadecimal floating point format. Prints the number in base 16 with
314    prefix <code>"0x"</code> and lower-case letters for digits above 9.
315    Uses <code>'p'</code> to indicate the exponent.
316  </td>
317</tr>
318<tr>
319  <td><code>'A'</code></td>
320  <td>
321    Same as <code>'a'</code> except it uses upper-case letters for the
322    prefix, digits above 9 and to indicate the exponent.
323  </td>
324</tr>
325<tr>
326  <td><code>'e'</code></td>
327  <td>
328    Exponent notation. Prints the number in scientific notation using
329    the letter 'e' to indicate the exponent.
330  </td>
331</tr>
332<tr>
333  <td><code>'E'</code></td>
334  <td>
335    Exponent notation. Same as <code>'e'</code> except it uses an
336    upper-case <code>'E'</code> as the separator character.
337  </td>
338</tr>
339<tr>
340  <td><code>'f'</code></td>
341  <td>Fixed point. Displays the number as a fixed-point number.</td>
342</tr>
343<tr>
344  <td><code>'F'</code></td>
345  <td>
346    Fixed point. Same as <code>'f'</code>, but converts <code>nan</code>
347    to <code>NAN</code> and <code>inf</code> to <code>INF</code>.
348  </td>
349</tr>
350<tr>
351  <td><code>'g'</code></td>
352  <td>
353    <p>General format. For a given precision <code>p &gt;= 1</code>,
354    this rounds the number to <code>p</code> significant digits and then
355    formats the result in either fixed-point format or in scientific
356    notation, depending on its magnitude.</p>
357    <p>A precision of <code>0</code> is treated as equivalent to a precision
358    of <code>1</code>.</p>
359  </td>
360</tr>
361<tr>
362  <td><code>'G'</code></td>
363  <td>
364    General format. Same as <code>'g'</code> except switches to
365    <code>'E'</code> if the number gets too large. The representations of
366    infinity and NaN are uppercased, too.
367  </td>
368</tr>
369<tr>
370  <td>none</td>
371  <td>
372    Similar to <code>'g'</code>, except that the default precision is as
373    high as needed to represent the particular value.
374  </td>
375</tr>
376</table>
377
378The available presentation types for pointers are:
379
380<table>
381<tr>
382  <th>Type</th>
383  <th>Meaning</th>
384</tr>
385<tr>
386  <td><code>'p'</code></td>
387  <td>
388    Pointer format. This is the default type for pointers and may be omitted.
389  </td>
390</tr>
391<tr>
392  <td>none</td>
393  <td>The same as <code>'p'</code>.</td>
394</tr>
395</table>
396
397## Chrono Format Specifications
398
399Format specifications for chrono duration and time point types as well as
400`std::tm` have the following syntax:
401
402<a id="chrono-format-spec"></a>
403<pre><code class="language-json"
404>chrono_format_spec ::= [[<a href="#format-spec">fill</a>]<a href="#format-spec"
405  >align</a>][<a href="#format-spec">width</a>]["." <a href="#format-spec"
406  >precision</a>][chrono_specs]
407chrono_specs       ::= conversion_spec |
408                       chrono_specs (conversion_spec | literal_char)
409conversion_spec    ::= "%" [padding_modifier] [locale_modifier] chrono_type
410literal_char       ::= &lt;a character other than '{', '}' or '%'>
411padding_modifier   ::= "-" | "_"  | "0"
412locale_modifier    ::= "E" | "O"
413chrono_type        ::= "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" |
414                       "F" | "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" |
415                       "n" | "p" | "q" | "Q" | "r" | "R" | "S" | "t" | "T" |
416                       "u" | "U" | "V" | "w" | "W" | "x" | "X" | "y" | "Y" |
417                       "z" | "Z" | "%"</code>
418</pre>
419
420Literal chars are copied unchanged to the output. Precision is valid only
421for `std::chrono::duration` types with a floating-point representation type.
422
423The available presentation types (*chrono_type*) are:
424
425<table>
426<tr>
427  <th>Type</th>
428  <th>Meaning</th>
429</tr>
430<tr>
431  <td><code>'a'</code></td>
432  <td>
433    The abbreviated weekday name, e.g. "Sat". If the value does not contain a
434    valid weekday, an exception of type <code>format_error</code> is thrown.
435  </td>
436</tr>
437<tr>
438  <td><code>'A'</code></td>
439  <td>
440    The full weekday name, e.g. "Saturday". If the value does not contain a
441    valid weekday, an exception of type <code>format_error</code> is thrown.
442  </td>
443</tr>
444<tr>
445  <td><code>'b'</code></td>
446  <td>
447    The abbreviated month name, e.g. "Nov". If the value does not contain a
448    valid month, an exception of type <code>format_error</code> is thrown.
449  </td>
450</tr>
451<tr>
452  <td><code>'B'</code></td>
453  <td>
454    The full month name, e.g. "November". If the value does not contain a valid
455    month, an exception of type <code>format_error</code> is thrown.
456  </td>
457</tr>
458<tr>
459  <td><code>'c'</code></td>
460  <td>
461    The date and time representation, e.g. "Sat Nov 12 22:04:00 1955". The
462    modified command <code>%Ec</code> produces the locale's alternate date and
463    time representation.
464  </td>
465</tr>
466<tr>
467  <td><code>'C'</code></td>
468  <td>
469    The year divided by 100 using floored division, e.g. "19". If the result
470    is a single decimal digit, it is prefixed with 0. The modified command
471    <code>%EC</code> produces the locale's alternative representation of the
472    century.
473  </td>
474</tr>
475<tr>
476  <td><code>'d'</code></td>
477  <td>
478    The day of month as a decimal number. If the result is a single decimal
479    digit, it is prefixed with 0. The modified command <code>%Od</code>
480    produces the locale's alternative representation.
481  </td>
482</tr>
483<tr>
484  <td><code>'D'</code></td>
485  <td>Equivalent to <code>%m/%d/%y</code>, e.g. "11/12/55".</td>
486</tr>
487<tr>
488  <td><code>'e'</code></td>
489  <td>
490    The day of month as a decimal number. If the result is a single decimal
491    digit, it is prefixed with a space. The modified command <code>%Oe</code>
492    produces the locale's alternative representation.
493  </td>
494</tr>
495<tr>
496  <td><code>'F'</code></td>
497  <td>Equivalent to <code>%Y-%m-%d</code>, e.g. "1955-11-12".</td>
498</tr>
499<tr>
500  <td><code>'g'</code></td>
501  <td>
502    The last two decimal digits of the ISO week-based year. If the result is a
503    single digit it is prefixed by 0.
504  </td>
505</tr>
506<tr>
507  <td><code>'G'</code></td>
508  <td>
509    The ISO week-based year as a decimal number. If the result is less than
510    four digits it is left-padded with 0 to four digits.
511  </td>
512</tr>
513<tr>
514  <td><code>'h'</code></td>
515  <td>Equivalent to <code>%b</code>, e.g. "Nov".</td>
516</tr>
517<tr>
518  <td><code>'H'</code></td>
519  <td>
520    The hour (24-hour clock) as a decimal number. If the result is a single
521    digit, it is prefixed with 0. The modified command <code>%OH</code>
522    produces the locale's alternative representation.
523  </td>
524</tr>
525<tr>
526  <td><code>'I'</code></td>
527  <td>
528    The hour (12-hour clock) as a decimal number. If the result is a single
529    digit, it is prefixed with 0. The modified command <code>%OI</code>
530    produces the locale's alternative representation.
531  </td>
532</tr>
533<tr>
534  <td><code>'j'</code></td>
535  <td>
536    If the type being formatted is a specialization of duration, the decimal
537    number of days without padding. Otherwise, the day of the year as a decimal
538    number. Jan 1 is 001. If the result is less than three digits, it is
539    left-padded with 0 to three digits.
540  </td>
541</tr>
542<tr>
543  <td><code>'m'</code></td>
544  <td>
545    The month as a decimal number. Jan is 01. If the result is a single digit,
546    it is prefixed with 0. The modified command <code>%Om</code> produces the
547    locale's alternative representation.
548  </td>
549</tr>
550<tr>
551  <td><code>'M'</code></td>
552  <td>
553    The minute as a decimal number. If the result is a single digit, it
554    is prefixed with 0. The modified command <code>%OM</code> produces the
555    locale's alternative representation.
556  </td>
557</tr>
558<tr>
559  <td><code>'n'</code></td>
560  <td>A new-line character.</td>
561</tr>
562<tr>
563  <td><code>'p'</code></td>
564  <td>The AM/PM designations associated with a 12-hour clock.</td>
565</tr>
566<tr>
567  <td><code>'q'</code></td>
568  <td>The duration's unit suffix.</td>
569</tr>
570<tr>
571  <td><code>'Q'</code></td>
572  <td>
573    The duration's numeric value (as if extracted via <code>.count()</code>).
574  </td>
575</tr>
576<tr>
577  <td><code>'r'</code></td>
578  <td>The 12-hour clock time, e.g. "10:04:00 PM".</td>
579</tr>
580<tr>
581  <td><code>'R'</code></td>
582  <td>Equivalent to <code>%H:%M</code>, e.g. "22:04".</td>
583</tr>
584<tr>
585  <td><code>'S'</code></td>
586  <td>
587    Seconds as a decimal number. If the number of seconds is less than 10, the
588    result is prefixed with 0. If the precision of the input cannot be exactly
589    represented with seconds, then the format is a decimal floating-point number
590    with a fixed format and a precision matching that of the precision of the
591    input (or to a microseconds precision if the conversion to floating-point
592    decimal seconds cannot be made within 18 fractional digits). The modified
593    command <code>%OS</code> produces the locale's alternative representation.
594  </td>
595</tr>
596<tr>
597  <td><code>'t'</code></td>
598  <td>A horizontal-tab character.</td>
599</tr>
600<tr>
601  <td><code>'T'</code></td>
602  <td>Equivalent to <code>%H:%M:%S</code>.</td>
603</tr>
604<tr>
605  <td><code>'u'</code></td>
606  <td>
607    The ISO weekday as a decimal number (1-7), where Monday is 1. The modified
608    command <code>%Ou</code> produces the locale's alternative representation.
609  </td>
610</tr>
611<tr>
612  <td><code>'U'</code></td>
613  <td>
614    The week number of the year as a decimal number. The first Sunday of the
615    year is the first day of week 01. Days of the same year prior to that are
616    in week 00. If the result is a single digit, it is prefixed with 0.
617    The modified command <code>%OU</code> produces the locale's alternative
618    representation.
619  </td>
620</tr>
621<tr>
622  <td><code>'V'</code></td>
623  <td>
624    The ISO week-based week number as a decimal number. If the result is a
625    single digit, it is prefixed with 0. The modified command <code>%OV</code>
626    produces the locale's alternative representation.
627  </td>
628</tr>
629<tr>
630  <td><code>'w'</code></td>
631  <td>
632    The weekday as a decimal number (0-6), where Sunday is 0. The modified
633    command <code>%Ow</code> produces the locale's alternative representation.
634  </td>
635</tr>
636<tr>
637  <td><code>'W'</code></td>
638  <td>
639    The week number of the year as a decimal number. The first Monday of the
640    year is the first day of week 01. Days of the same year prior to that are
641    in week 00. If the result is a single digit, it is prefixed with 0.
642    The modified command <code>%OW</code> produces the locale's alternative
643    representation.
644  </td>
645</tr>
646<tr>
647  <td><code>'x'</code></td>
648  <td>
649    The date representation, e.g. "11/12/55". The modified command
650    <code>%Ex</code> produces the locale's alternate date representation.
651  </td>
652</tr>
653<tr>
654  <td><code>'X'</code></td>
655  <td>
656    The time representation, e.g. "10:04:00". The modified command
657    <code>%EX</code> produces the locale's alternate time representation.
658  </td>
659</tr>
660<tr>
661  <td><code>'y'</code></td>
662  <td>
663    The last two decimal digits of the year. If the result is a single digit
664    it is prefixed by 0. The modified command <code>%Oy</code> produces the
665    locale's alternative representation. The modified command <code>%Ey</code>
666    produces the locale's alternative representation of offset from
667    <code>%EC</code> (year only).
668  </td>
669</tr>
670<tr>
671  <td><code>'Y'</code></td>
672  <td>
673    The year as a decimal number. If the result is less than four digits it is
674    left-padded with 0 to four digits. The modified command <code>%EY</code>
675    produces the locale's alternative full year representation.
676  </td>
677</tr>
678<tr>
679  <td><code>'z'</code></td>
680  <td>
681    The offset from UTC in the ISO 8601:2004 format. For example -0430 refers
682    to 4 hours 30 minutes behind UTC. If the offset is zero, +0000 is used.
683    The modified commands <code>%Ez</code> and <code>%Oz</code> insert a
684    <code>:</code> between the hours and minutes: -04:30. If the offset
685    information is not available, an exception of type
686    <code>format_error</code> is thrown.
687  </td>
688</tr>
689<tr>
690  <td><code>'Z'</code></td>
691  <td>
692    The time zone abbreviation. If the time zone abbreviation is not available,
693    an exception of type <code>format_error</code> is thrown.
694  </td>
695</tr>
696<tr>
697  <td><code>'%'</code></td>
698  <td>A % character.</td>
699</tr>
700</table>
701
702Specifiers that have a calendaric component such as `'d'` (the day of month)
703are valid only for `std::tm` and time points but not durations.
704
705The available padding modifiers (*padding_modifier*) are:
706
707| Type  | Meaning                                 |
708|-------|-----------------------------------------|
709| `'-'` | Pad a numeric result with spaces.       |
710| `'_'` | Do not pad a numeric result string.     |
711| `'0'` | Pad a numeric result string with zeros. |
712
713These modifiers are only supported for the `'H'`, `'I'`, `'M'`, `'S'`, `'U'`,
714`'V'`, `'W'`, `'m'`, `'j'`, `'Y'` presentation types.
715
716## Range Format Specifications
717
718Format specifications for range types have the following syntax:
719
720<pre><code class="language-json"
721>range_format_spec ::= ["n"][range_type][range_underlying_spec]</code>
722</pre>
723
724The `'n'` option formats the range without the opening and closing brackets.
725
726The available presentation types for `range_type` are:
727
728| Type   | Meaning                                                    |
729|--------|------------------------------------------------------------|
730| none   | Default format.                                            |
731| `'s'`  | String format. The range is formatted as a string.         |
732| `'?⁠s'` | Debug format. The range is formatted as an escaped string. |
733
734If `range_type` is `'s'` or `'?s'`, the range element type must be a character
735type. The `'n'` option and `range_underlying_spec` are mutually exclusive with
736`'s'` and `'?s'`.
737
738The `range_underlying_spec` is parsed based on the formatter of the range's
739element type.
740
741By default, a range of characters or strings is printed escaped and quoted.
742But if any `range_underlying_spec` is provided (even if it is empty), then the
743characters or strings are printed according to the provided specification.
744
745Examples:
746
747```c++
748fmt::print("{}", std::vector{10, 20, 30});
749// Output: [10, 20, 30]
750fmt::print("{::#x}", std::vector{10, 20, 30});
751// Output: [0xa, 0x14, 0x1e]
752fmt::print("{}", std::vector{'h', 'e', 'l', 'l', 'o'});
753// Output: ['h', 'e', 'l', 'l', 'o']
754fmt::print("{:n}", std::vector{'h', 'e', 'l', 'l', 'o'});
755// Output: 'h', 'e', 'l', 'l', 'o'
756fmt::print("{:s}", std::vector{'h', 'e', 'l', 'l', 'o'});
757// Output: "hello"
758fmt::print("{:?s}", std::vector{'h', 'e', 'l', 'l', 'o', '\n'});
759// Output: "hello\n"
760fmt::print("{::}", std::vector{'h', 'e', 'l', 'l', 'o'});
761// Output: [h, e, l, l, o]
762fmt::print("{::d}", std::vector{'h', 'e', 'l', 'l', 'o'});
763// Output: [104, 101, 108, 108, 111]
764```
765
766## Format Examples
767
768This section contains examples of the format syntax and comparison with
769the printf formatting.
770
771In most of the cases the syntax is similar to the printf formatting,
772with the addition of the `{}` and with `:` used instead of `%`. For
773example, `"%03.2f"` can be translated to `"{:03.2f}"`.
774
775The new format syntax also supports new and different options, shown in
776the following examples.
777
778Accessing arguments by position:
779
780```c++
781fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
782// Result: "a, b, c"
783fmt::format("{}, {}, {}", 'a', 'b', 'c');
784// Result: "a, b, c"
785fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
786// Result: "c, b, a"
787fmt::format("{0}{1}{0}", "abra", "cad");  // arguments' indices can be repeated
788// Result: "abracadabra"
789```
790
791Aligning the text and specifying a width:
792
793```c++
794fmt::format("{:<30}", "left aligned");
795// Result: "left aligned                  "
796fmt::format("{:>30}", "right aligned");
797// Result: "                 right aligned"
798fmt::format("{:^30}", "centered");
799// Result: "           centered           "
800fmt::format("{:*^30}", "centered");  // use '*' as a fill char
801// Result: "***********centered***********"
802```
803
804Dynamic width:
805
806```c++
807fmt::format("{:<{}}", "left aligned", 30);
808// Result: "left aligned                  "
809```
810
811Dynamic precision:
812
813```c++
814fmt::format("{:.{}f}", 3.14, 1);
815// Result: "3.1"
816```
817
818Replacing `%+f`, `%-f`, and `% f` and specifying a sign:
819
820```c++
821fmt::format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
822// Result: "+3.140000; -3.140000"
823fmt::format("{: f}; {: f}", 3.14, -3.14);  // show a space for positive numbers
824// Result: " 3.140000; -3.140000"
825fmt::format("{:-f}; {:-f}", 3.14, -3.14);  // show only the minus -- same as '{:f}; {:f}'
826// Result: "3.140000; -3.140000"
827```
828
829Replacing `%x` and `%o` and converting the value to different bases:
830
831```c++
832fmt::format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
833// Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
834// with 0x or 0 or 0b as prefix:
835fmt::format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
836// Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"
837```
838
839Padded hex byte with prefix and always prints both hex characters:
840
841```c++
842fmt::format("{:#04x}", 0);
843// Result: "0x00"
844```
845
846Box drawing using Unicode fill:
847
848```c++
849fmt::print(
850    "┌{0:─^{2}}┐\n"
851    "│{1: ^{2}}│\n"
852    "└{0:─^{2}}┘\n", "", "Hello, world!", 20);
853```
854
855prints:
856
857```
858┌────────────────────┐
859│   Hello, world!    │
860└────────────────────┘
861```
862
863Using type-specific formatting:
864
865```c++
866#include <fmt/chrono.h>
867
868auto t = tm();
869t.tm_year = 2010 - 1900;
870t.tm_mon = 7;
871t.tm_mday = 4;
872t.tm_hour = 12;
873t.tm_min = 15;
874t.tm_sec = 58;
875fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
876// Prints: 2010-08-04 12:15:58
877```
878
879Using the comma as a thousands separator:
880
881```c++
882#include <fmt/format.h>
883
884auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
885// s == "1,234,567,890"
886```
887