Namespaces
Variants

Standard format specification (since C++20)

From cppreference.net

Für grundlegende Typen und String-Typen basiert die Formatangabe auf der Formatangabe in Python .

Die Syntax der Formatspezifikationen lautet:

Füllung-und-Ausrichtung  (optional) Vorzeichen  (optional) # (optional) 0 (optional) Breite  (optional) Genauigkeit  (optional) L (optional) Typ  (optional)

Die sign , # und 0 Optionen sind nur gültig, wenn ein Integer- oder Gleitkomma-Präsentationstyp verwendet wird.

Inhaltsverzeichnis

Füllen und Ausrichten

fill-and-align ist ein optionales fill -Zeichen (das ein beliebiges Zeichen außer { oder } sein kann), gefolgt von einer der align -Optionen < , > , ^ .

Wenn kein Füllzeichen angegeben ist, wird standardmäßig das Leerzeichen verwendet. Für eine Formatangabe in einer Unicode-Kodierung muss das Füllzeichen einem einzelnen Unicode-Skalarwert entsprechen.

Die Bedeutung der align -Optionen ist wie folgt:

  • < : Erzwingt die Ausrichtung des formatierten Arguments am Anfang des verfügbaren Raums durch Einfügen von n Füllzeichen nach dem formatierten Argument. Dies ist die Standardeinstellung, wenn ein nicht-ganzzahliger, nicht-Gleitkomma-Präsentationstyp verwendet wird.
  • > : Erzwingt die Ausrichtung des formatierten Arguments am Ende des verfügbaren Raums durch Einfügen von n Füllzeichen vor dem formatierten Argument. Dies ist die Standardeinstellung, wenn ein ganzzahliger oder Gleitkomma-Präsentationstyp verwendet wird.
  • ^ : Erzwingt die Zentrierung des formatierten Arguments innerhalb des verfügbaren Raums durch Einfügen von
    n
    2
    Zeichen vor und
    n
    2
    Zeichen nach dem formatierten Argument.

In jedem Fall ist n die Differenz zwischen der minimalen Feldbreite (angegeben durch width ) und der geschätzten Breite des formatierten Arguments, oder 0, wenn die Differenz kleiner als 0 ist.

#include <cassert>
#include <format>
int main()
{
    char c = 120;
    assert(std::format("{:6}", 42)    == "    42");
    assert(std::format("{:6}", 'x')   == "x     ");
    assert(std::format("{:*<6}", 'x') == "x*****");
    assert(std::format("{:*>6}", 'x') == "*****x");
    assert(std::format("{:*^6}", 'x') == "**x***");
    assert(std::format("{:6d}", c)    == "   120");
    assert(std::format("{:6}", true)  == "true  ");
}

Vorzeichen, # und 0

Die sign -Option kann einer der folgenden Werte sein:

  • + : Gibt an, dass ein Vorzeichen sowohl für nicht-negative als auch für negative Zahlen verwendet werden soll. Das + -Zeichen wird vor dem Ausgabewert für nicht-negative Zahlen eingefügt.
  • - : Gibt an, dass ein Vorzeichen nur für negative Zahlen verwendet werden soll (dies ist das Standardverhalten).
  • Leerzeichen: Gibt an, dass für nicht-negative Zahlen ein führendes Leerzeichen und für negative Zahlen ein Minuszeichen verwendet werden soll.

Negative Null wird als negative Zahl behandelt.

Die sign -Option gilt für Gleitkomma-Unendlich und 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");
}

Die # -Option bewirkt, dass die alternative Form für die Konvertierung verwendet wird.

  • Für Ganzzahltypen fügt die alternative Form, wenn binäre, oktale oder hexadezimale Darstellungsarten verwendet werden, das Präfix ( 0b , 0 , oder 0x ) in den Ausgabewert nach dem Vorzeichen (möglicherweise Leerzeichen) ein, falls vorhanden, oder fügt es andernfalls vor den Ausgabewert hinzu.
  • Für Gleitkommatypen bewirkt die alternative Form, dass das Ergebnis der Konvertierung endlicher Werte immer ein Dezimaltrennzeichen enthält, selbst wenn keine Ziffern darauf folgen. Normalerweise erscheint ein Dezimaltrennzeichen im Ergebnis dieser Konvertierungen nur, wenn eine Ziffer darauf folgt. Zusätzlich werden für g und G Konvertierungen nachfolgende Nullen nicht aus dem Ergebnis entfernt.

Die 0 -Option füllt das Feld mit führenden Nullen (nach etwaigen Vorzeichen- oder Basisangaben) bis zur Feldbreite auf, außer bei Unendlich oder NaN. Wenn das 0 -Zeichen und eine align -Option beide erscheinen, wird das 0 -Zeichen ignoriert.

#include <cassert>
#include <format>
int main()
{
    char c = 120;
    assert(std::format("{:+06d}", c)   == "+00120");
    assert(std::format("{:#06x}", 0xa) == "0x000a");
    assert(std::format("{:<06}", -42)  == "-42   "); // 0 wird wegen '<' ignoriert
}

Breite und Genauigkeit

width ist entweder eine positive Dezimalzahl oder ein verschachteltes Ersatzfeld ( {} oder { n } ). Falls vorhanden, gibt es die minimale Feldbreite an.

precision ist ein Punkt ( . ) gefolgt von entweder einer nicht-negativen Dezimalzahl oder einem verschachtelten Ersatzfeld. Dieses Feld gibt die Genauigkeit oder maximale Feldgröße an. Es kann nur mit Gleitkomma- und Zeichenkettentypen verwendet werden.

  • Für Gleitkommatypen gibt dieses Feld die Formatierungsgenauigkeit an.
  • Für String-Typen gibt es eine obere Schranke für die geschätzte Breite (siehe unten ) des Präfixes des Strings, der in die Ausgabe kopiert werden soll. Für einen String in einer Unicode-Kodierung ist der in die Ausgabe zu kopierende Text das längste Präfix ganzer erweiterter Graphem-Cluster, dessen geschätzte Breite nicht größer als die Genauigkeit ist.

Wenn ein verschachteltes Ersatzfeld für width oder precision verwendet wird und das entsprechende Argument nicht vom integral type (until C++23) standard signed or unsigned integer type (since C++23) ist oder negativ ist, wird eine Ausnahme vom Typ std::format_error ausgelöst.

float pi = 3.14f;
assert(std::format("{:10f}", pi)           == "  3.140000"); // Breite = 10
assert(std::format("{:{}f}", pi, 10)       == "  3.140000"); // Breite = 10
assert(std::format("{:.5f}", pi)           == "3.14000");    // Genauigkeit = 5
assert(std::format("{:.{}f}", pi, 5)       == "3.14000");    // Genauigkeit = 5
assert(std::format("{:10.5f}", pi)         == "   3.14000"); // Breite = 10, Genauigkeit = 5
assert(std::format("{:{}.{}f}", pi, 10, 5) == "   3.14000"); // Breite = 10, Genauigkeit = 5
auto b1 = std::format("{:{}f}", pi, 10.0); // wirft Exception: Breite ist kein integraler Typ
auto b2 = std::format("{:{}f}", pi, -10);  // wirft Exception: Breite ist negativ
auto b3 = std::format("{:.{}f}", pi, 5.0); // wirft Exception: Genauigkeit ist kein integraler Typ

Die Breite einer Zeichenkette ist definiert als die geschätzte Anzahl von Spaltenpositionen, die für ihre Anzeige in einem Terminal geeignet sind.

Für die Zwecke der Breitenberechnung wird angenommen, dass eine Zeichenkette in einer implementierungsdefinierten Kodierung vorliegt. Die Methode der Breitenberechnung ist nicht spezifiziert, aber für eine Zeichenkette in einer Unicode-Kodierung sollte die Implementierung die Breite der Zeichenkette als die Summe der geschätzten Breiten der ersten Code Points in ihren erweiterten Graphem-Clustern schätzen. Die geschätzte Breite beträgt 2 für die folgenden Code Points und ist ansonsten 1:

  • Jeder Codepunkt, dessen Unicode-Eigenschaft East_Asian_Width den Wert Fullwidth ( F ) oder Wide ( W ) hat
  • U+4DC0 - U+4DFF (Yijing-Hexagrammsymbole)
  • U+1F300 – U+1F5FF (Verschiedene Symbole und Piktogramme)
  • U+1F900 – U+1F9FF (Ergänzende Symbole und Piktogramme)
#include <cassert>
#include <format>
int main()
{
    assert(std::format("{:.^5s}",   "🐱")    == ".🐱..");
    assert(std::format("{:.5s}",    "🐱🐱🐱") == "🐱🐱");
    assert(std::format("{:.<5.5s}", "🐱🐱🐱") == "🐱🐱.");
}

L (lokalspezifische Formatierung)

Die L Option bewirkt, dass die lokalisierte Form verwendet wird. Diese Option ist nur für arithmetische Typen gültig.

  • Für Ganzzahltypen fügt die gebietsschemaspezifische Form die entsprechenden Zifferngruppentrennzeichen gemäß dem Gebietsschema des Kontexts ein.
  • Für Gleitkommatypen fügt die gebietsschemaspezifische Form die entsprechenden Zifferngruppen- und Radix-Trennzeichen gemäß dem Gebietsschema des Kontexts ein.
  • Für die textuelle Darstellung von bool verwendet die gebietsschemaspezifische Form die entsprechende Zeichenkette, als ob sie mit std::numpunct::truename oder std::numpunct::falsename erhalten worden wäre.

Typ

Die type Option bestimmt, wie die Daten dargestellt werden sollten.

Die verfügbaren String-Präsentationstypen sind:

  • none, s : Kopiert die Zeichenkette zur Ausgabe.
  • ? : Kopiert die maskierte Zeichenkette (siehe unten ) in die Ausgabe.
(seit C++23)

Die verfügbaren Integer-Präsentationstypen für integrale Typen außer char , wchar_t und bool sind:

  • b : Binärformat. Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, 2 ) . Das Basispräfix ist 0b .
  • B : Gleich wie b , außer dass das Basispräfix 0B ist.
  • c : Kopiert das Zeichen static_cast < CharT > ( value ) in die Ausgabe, wobei CharT der Zeichentyp der Formatzeichenkette ist. Wirft std::format_error , wenn der Wert nicht im darstellbaren Wertebereich für CharT liegt.
  • d : Dezimalformat. Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value ) .
  • o : Oktalformat. Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, 8 ) . Das Basispräfix ist 0 , wenn der entsprechende Argumentwert ungleich null ist, andernfalls leer.
  • x : Hexadezimalformat. Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, 16 ) . Das Basispräfix ist 0x .
  • X : Gleich wie x , außer dass Großbuchstaben für Ziffern über 9 verwendet werden und das Basispräfix 0X ist.
  • nichts: Gleich wie d .

Die verfügbaren char und wchar_t Präsentationstypen sind:

  • none, c : Kopiert das Zeichen in die Ausgabe.
  • b , B , d , o , x , X : Verwendet Ganzzahl-Darstellungstypen mit dem Wert static_cast < unsigned char > ( value ) oder static_cast < std:: make_unsigned_t < wchar_t >> ( value ) entsprechend.
  • ? : Kopiert das maskierte Zeichen (siehe unten ) zur Ausgabe.
(since C++23)

Die verfügbaren bool Präsentationstypen sind:

  • none, s : Kopiert die textuelle Darstellung ( true oder false , oder die lokalisierte Form) in die Ausgabe.
  • b , B , d , o , x , X : Verwendet Ganzzahl-Darstellungstypen mit dem Wert static_cast < unsigned char > ( value ) .

Die verfügbaren Gleitkomma-Darstellungstypen sind:

  • a : Wenn precision angegeben ist, erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: hex , precision ) , wobei precision die angegebene Präzision ist; andernfalls wird die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: hex ) erzeugt.
  • A : Gleich wie a , außer dass Großbuchstaben für Ziffern über 9 verwendet werden und P zur Anzeige des Exponenten dient.
  • e : Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: scientific , precision ) , wobei precision die angegebene Präzision ist, oder 6 falls keine Präzision angegeben wurde.
  • E : Gleich wie e , außer dass E zur Anzeige des Exponenten verwendet wird.
  • f , F : Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: fixed , precision ) , wobei precision die angegebene Präzision ist, oder 6 falls keine Präzision angegeben wurde.
  • g : Erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) , wobei precision die angegebene Präzision ist, oder 6 falls keine Präzision angegeben wurde.
  • G : Gleich wie g , außer dass E zur Anzeige des Exponenten verwendet wird.
  • none: Wenn precision angegeben ist, erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) , wobei precision die angegebene Präzision ist; andernfalls wird die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, value ) erzeugt.

Für Kleinbuchstaben-Darstellungstypen werden Unendlich und NaN als inf und nan formatiert. Für Großbuchstaben-Darstellungstypen werden Unendlich und NaN als INF und NAN formatiert.

std::format Spezifizierer std::chars_format Entsprechender std::printf Spezifizierer
a , A std::chars_format::hex a , A (aber std::format gibt kein führendes 0x oder 0X aus)
e , E std::chars_format::scientific e , E
f , F std::chars_format::fixed f , F
g , G std::chars_format::general g , G
Keiner std::chars_format::general wenn Genauigkeit spezifiziert ist, andernfalls das kürzeste Round-Trip-Format g wenn Genauigkeit spezifiziert ist. Andernfalls gibt es keinen entsprechenden Spezifizierer.

Die verfügbaren Zeiger-Präsentationstypen (auch verwendet für std::nullptr_t ) sind:

  • none, p : Falls std::uintptr_t definiert ist, erzeugt die Ausgabe wie durch Aufruf von std:: to_chars ( first, last, reinterpret_cast < std:: uintptr_t > ( value ) , 16 ) mit dem Präfix 0x zur Ausgabe hinzugefügt; andernfalls ist die Ausgabe implementierungsdefiniert.
  • P : identisch mit p , außer dass Großbuchstaben für Ziffern über 9 verwendet werden und das Basispräfix 0X lautet.
(seit C++26)


Formatierung von Escape-Zeichen und Zeichenketten

Ein Zeichen oder eine Zeichenkette kann als escaped formatiert werden, um es besser für Debugging oder Protokollierung geeignet zu machen.

Das Escaping erfolgt wie folgt:

  • Für jede wohlgeformte Codeeinheiten-Sequenz, die ein Zeichen C kodiert:
  • Wenn C eines der Zeichen in der folgenden Tabelle ist, wird die entsprechende Escape-Sequenz verwendet.
Zeichen Escape-Sequenz Anmerkungen
horizontaler Tabulator (Byte 0x09 in ASCII-Kodierung) \t
Zeilenvorschub - neue Zeile (Byte 0x0a in ASCII-Kodierung) \n
Wagenrücklauf (Byte 0x0d in ASCII-Kodierung) \r
doppeltes Anführungszeichen (Byte 0x22 in ASCII-Kodierung) \" Wird nur verwendet, wenn die Ausgabe eine doppelt-gekennzeichnete Zeichenkette ist
einfaches Anführungszeichen (Byte 0x27 in ASCII-Kodierung) \' Wird nur verwendet, wenn die Ausgabe eine einfach-gekennzeichnete Zeichenkette ist
Backslash (Byte 0x5c in ASCII-Kodierung) \\
  • Andernfalls, wenn C nicht das Leerzeichen (Byte 0x20 in ASCII-Kodierung) ist, und entweder
  • die zugehörige Zeichenkodierung eine Unicode-Kodierung ist und
  • C einem Unicode-Skalarwert entspricht, dessen Unicode-Eigenschaft General_Category einen Wert in den Gruppen Separator ( Z ) oder Other ( C ) hat, oder
  • C nicht unmittelbar von einem nicht-escaped Zeichen vorangegangen wird, und C einem Unicode-Skalarwert entspricht, der die Unicode-Eigenschaft Grapheme_Extend=Yes hat, oder
  • die zugehörige Zeichenkodierung keine Unicode-Kodierung ist und C eines einer implementierungsdefinierten Menge von Trenn- oder nicht-druckbaren Zeichen ist
ist die Escape-Sequenz \u{ hex-digit-sequence } , wobei hex-digit-sequence die kürzeste hexadezimale Darstellung von C unter Verwendung von Kleinbuchstaben für hexadezimale Ziffern ist.
  • Andernfalls wird C unverändert kopiert.
  • Eine Codeeinheiten-Sequenz, die eine Shift-Sequenz ist, hat einen nicht spezifizierten Effekt auf die Ausgabe und weitere Dekodierung der Zeichenkette.
  • Andere Codeeinheiten (d.h. solche in fehlerhaften Codeeinheiten-Sequenzen) werden jeweils ersetzt durch \x{ hex-digit-sequence } , wobei hex-digit-sequence die kürzeste hexadezimale Darstellung der Codeeinheit unter Verwendung von Kleinbuchstaben für hexadezimale Ziffern ist.

Die escaped Zeichenketten-Darstellung einer Zeichenkette wird konstruiert, indem die Codeeinheiten-Sequenzen in der Zeichenkette, wie oben beschrieben, escaped und das Ergebnis mit doppelten Anführungszeichen gekennzeichnet wird.

Die escaped Darstellung eines Zeichens wird konstruiert, indem es wie oben beschrieben escaped und das Ergebnis mit einfachen Anführungszeichen gekennzeichnet wird.

Compiler Explorer Demo :

#include <print>
int main()
{
    std::println("[{:?}]", "h\tllo");             // gibt aus: ["h\tllo"]
    std::println("[{:?}]", "Спасибо, Виктор ♥!"); // gibt aus: ["Спасибо, Виктор ♥!"]
    std::println("[{:?}] [{:?}]", '\'', '"');     // gibt aus: ['\'', '"']
    // Die folgenden Beispiele setzen die Verwendung der UTF-8-Kodierung voraus
    std::println("[{:?}]", std::string("\0 \n \t \x02 \x1b", 9));
                                             // gibt aus: ["\u{0} \n \t \u{2} \u{1b}"]
    std::println("[{:?}]", "\xc3\x28");      // ungültiges UTF-8
                                             // gibt aus: ["\x{c3}("]
    std::println("[{:?}]", "\u0301");        // gibt aus: ["\u{301}"]
    std::println("[{:?}]", "\\\u0301");      // gibt aus: ["\\\u{301}"]
    std::println("[{:?}]", "e\u0301\u0323"); // gibt aus: ["ẹ́"]
}
(seit C++23)

Hinweise

In den meisten Fällen ist die Syntax ähnlich zur alten % -Formatierung, mit der Ergänzung der {} und mit : anstelle von % . Zum Beispiel, "%03.2f" kann übersetzt werden zu "{:03.2f}" .

Feature-Test Makro Wert Std Funktion
__cpp_lib_format_uchar 202311L (C++20)
(DR)
Formatierung von Codeeinheiten als vorzeichenlose Ganzzahlen

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 3721 C++20 Null ist für das Breitenfeld nicht erlaubt
in der Standardformat-Spezifikation
Null ist erlaubt, wenn angegeben
über ein Ersatzfeld
P2909R4 C++20 char oder wchar_t könnten formatiert werden als
vorzeichenlose Ganzzahlwerte außerhalb des Bereichs
Code-Einheiten werden vor einer solchen Formatierung
in den entsprechenden vorzeichenlosen Typ konvertiert