Standard format specification (since C++20)
Pour les types de base et les types chaîne, la spécification de format est basée sur la spécification de format en Python .
La syntaxe des spécifications de format est :
fill-and-align
(optionnel)
sign
(optionnel)
#
(optionnel)
0
(optionnel)
width
(optionnel)
precision
(optionnel)
L
(optionnel)
type
(optionnel)
|
|||||||||
Les options
signe
,
#
et
0
ne sont valides que lorsqu'un type de présentation entier ou à virgule flottante est utilisé.
Table des matières |
Remplissage et alignement
fill-and-align
est un caractère de
remplissage
optionnel (qui peut être n'importe quel caractère autre que
{
ou
}
), suivi par l'une des options d'
alignement
<
,
>
,
^
.
Si aucun caractère de remplissage n'est spécifié, il prend par défaut le caractère d'espace. Pour une spécification de format dans un encodage Unicode, le caractère de remplissage doit correspondre à une valeur scalaire Unicode unique.
La signification des options align est la suivante :
-
<: Force l'argument formaté à s'aligner au début de l'espace disponible en insérant n caractères de remplissage après l'argument formaté. Ceci est le comportement par défaut lorsqu'un type de présentation non entier et non flottant est utilisé. -
>: Force l'argument formaté à s'aligner à la fin de l'espace disponible en insérant n caractères de remplissage avant l'argument formaté. Ceci est le comportement par défaut lorsqu'un type de présentation entier ou flottant est utilisé. -
^: Force l'argument formaté à être centré dans l'espace disponible en insérant ⌊
⌋ caractères avant et ⌈n 2
⌉ caractères après l'argument formaté.n 2
Dans chaque cas, n représente la différence entre la largeur minimale du champ (spécifiée par width ) et la largeur estimée de l'argument formaté, ou 0 si la différence est inférieure à 0.
#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 "); }
Signe, #, et 0
L'option sign peut être l'une des suivantes :
-
+: Indique qu'un signe doit être utilisé pour les nombres non négatifs et négatifs. Le signe+est inséré avant la valeur de sortie pour les nombres non négatifs. -
-: Indique qu'un signe doit être utilisé uniquement pour les nombres négatifs (comportement par défaut). - espace : Indique qu'un espace initial doit être utilisé pour les nombres non négatifs, et un signe moins pour les nombres négatifs.
Le zéro négatif est traité comme un nombre négatif.
L'option de signe s'applique à l'infini et au NaN en virgule flottante.
#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"); }
L'option
#
provoque l'utilisation de la
forme alternative
pour la conversion.
-
Pour les types entiers, lorsque la présentation binaire, octale ou hexadécimale est utilisée, la forme alternative insère le préfixe (
0b,0, ou0x) dans la valeur de sortie après le caractère de signe (éventuellement un espace) s'il y en a un, ou l'ajoute avant la valeur de sortie sinon. -
Pour les types à virgule flottante, la forme alternative entraîne que le résultat de la conversion des valeurs finies contienne toujours un caractère de point décimal, même si aucun chiffre ne le suit. Normalement, un caractère de point décimal apparaît dans le résultat de ces conversions uniquement si un chiffre le suit. De plus, pour les conversions
getG, les zéros de fin ne sont pas supprimés du résultat.
L'option
0
remplit le champ avec des zéros non significatifs (après toute indication de signe ou de base) jusqu'à la largeur du champ, sauf lorsqu'elle est appliquée à un infini ou un NaN. Si le caractère
0
et une option d'
alignement
apparaissent tous deux, le caractère
0
est ignoré.
#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 est ignoré à cause de '<' }
Largeur et précision
width
est soit un nombre décimal positif, soit un champ de remplacement imbriqué (
{}
ou
{
n
}
). S'il est présent, il spécifie la largeur minimale du champ.
precision
est un point (
.
) suivi soit d'un nombre décimal non négatif, soit d'un champ de remplacement imbriqué. Ce champ indique la précision ou la taille maximale du champ. Il ne peut être utilisé qu'avec les types à virgule flottante et les chaînes de caractères.
- Pour les types à virgule flottante, ce champ spécifie la précision du formatage.
- Pour les types chaîne de caractères, il fournit une limite supérieure pour la largeur estimée (voir ci-dessous ) du préfixe de la chaîne à copier vers la sortie. Pour une chaîne dans un encodage Unicode, le texte à copier vers la sortie est le préfixe le plus long de graphemes étendus complets dont la largeur estimée n'est pas supérieure à la précision.
Si un champ de remplacement imbriqué est utilisé pour width ou precision , et que l'argument correspondant n'est pas de integral type (until C++23) standard signed or unsigned integer type (since C++23) , ou est négatif, une exception de type std::format_error est levée.
float pi = 3.14f; assert(std::format("{:10f}", pi) == " 3.140000"); // largeur = 10 assert(std::format("{:{}f}", pi, 10) == " 3.140000"); // largeur = 10 assert(std::format("{:.5f}", pi) == "3.14000"); // précision = 5 assert(std::format("{:.{}f}", pi, 5) == "3.14000"); // précision = 5 assert(std::format("{:10.5f}", pi) == " 3.14000"); // largeur = 10, précision = 5 assert(std::format("{:{}.{}f}", pi, 10, 5) == " 3.14000"); // largeur = 10, précision = 5 auto b1 = std::format("{:{}f}", pi, 10.0); // lève une exception : la largeur n'est pas de type intégral auto b2 = std::format("{:{}f}", pi, -10); // lève une exception : la largeur est négative auto b3 = std::format("{:.{}f}", pi, 5.0); // lève une exception : la précision n'est pas de type intégral
La largeur d'une chaîne est définie comme le nombre estimé de positions de colonnes appropriées pour l'afficher dans un terminal.
Pour le calcul de la largeur, une chaîne est supposée être dans un encodage défini par l'implémentation. La méthode de calcul de la largeur n'est pas spécifiée, mais pour une chaîne dans un encodage Unicode, l'implémentation doit estimer la largeur de la chaîne comme la somme des largeurs estimées des premiers points de code dans ses graphemes étendus . La largeur estimée est de 2 pour les points de code suivants, et de 1 autrement :
-
Tout point de code dont la propriété Unicode
East_Asian_Widtha la valeur Pleine largeur (F) ou Large (W) - U+4DC0 - U+4DFF (Symboles des hexagrammes du Yijing)
- U+1F300 – U+1F5FF (Symboles et pictogrammes divers)
- U+1F900 – U+1F9FF (Symboles et pictogrammes supplémentaires)
#include <cassert> #include <format> int main() { assert(std::format("{:.^5s}", "🐱") == ".🐱.."); assert(std::format("{:.5s}", "🐱🐱🐱") == "🐱🐱"); assert(std::format("{:.<5.5s}", "🐱🐱🐱") == "🐱🐱."); }
L (formatage spécifique aux paramètres régionaux)
L'option
L
entraîne l'utilisation de la forme spécifique aux paramètres régionaux. Cette option n'est valide que pour les types arithmétiques.
- Pour les types entiers, la forme spécifique aux paramètres régionaux insère les caractères de séparation de groupes de chiffres appropriés selon les paramètres régionaux du contexte.
- Pour les types à virgule flottante, la forme spécifique aux paramètres régionaux insère les caractères de séparation de groupes de chiffres et de séparation décimale appropriés selon les paramètres régionaux du contexte.
-
Pour la représentation textuelle de
bool, la forme spécifique aux paramètres régionaux utilise la chaîne appropriée comme si elle était obtenue avec std::numpunct::truename ou std::numpunct::falsename .
Type
L'option type détermine comment les données doivent être présentées.
Les types de présentation de chaîne disponibles sont :
-
none,
s: Copie la chaîne vers la sortie.
|
(depuis C++23) |
Les types de présentation entiers disponibles pour les types intégraux autres que char , wchar_t , et bool sont :
-
b: Format binaire. Produit la sortie comme en appelant std:: to_chars ( first, last, value, 2 ) . Le préfixe de base est0b. -
B: identique àb, sauf que le préfixe de base est0B. -
c: Copie le caractère static_cast < CharT > ( value ) vers la sortie, oùCharTest le type de caractère de la chaîne de format. Lance std::format_error si la valeur n'est pas dans la plage des valeurs représentables pourCharT. -
d: Format décimal. Produit la sortie comme en appelant std:: to_chars ( first, last, value ) . -
o: Format octal. Produit la sortie comme en appelant std:: to_chars ( first, last, value, 8 ) . Le préfixe de base est0si la valeur d'argument correspondante est non nulle et est vide sinon. -
x: Format hexadécimal. Produit la sortie comme en appelant std:: to_chars ( first, last, value, 16 ) . Le préfixe de base est0x. -
X: identique àx, sauf qu'il utilise des lettres majuscules pour les chiffres au-dessus de 9 et le préfixe de base est0X. -
aucun : identique à
d.
Les types de présentation disponibles pour char et wchar_t sont :
-
none,
c: Copie le caractère vers la sortie. -
b,B,d,o,x,X: Utilise les types de présentation entiers avec la valeur static_cast < unsigned char > ( value ) ou static_cast < std:: make_unsigned_t < wchar_t >> ( value ) respectivement.
|
(depuis C++23) |
Les types de présentation disponibles pour bool sont :
-
none,
s: Copie la représentation textuelle (trueoufalse, ou la forme spécifique à la locale) vers la sortie. -
b,B,d,o,x,X: Utilise les types de présentation entière avec la valeur static_cast < unsigned char > ( value ) .
Les types de présentation en virgule flottante disponibles sont :
-
a: Si precision est spécifiée, produit le résultat comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: hex , precision ) où precision est la précision spécifiée ; sinon, le résultat est produit comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: hex ) . -
A: identique àa, sauf qu'il utilise des lettres majuscules pour les chiffres au-dessus de 9 et utilisePpour indiquer l'exposant. -
e: Produit le résultat comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: scientific , precision ) où precision est la précision spécifiée, ou 6 si la précision n'est pas spécifiée. -
E: identique àe, sauf qu'il utiliseEpour indiquer l'exposant. -
f,F: Produit le résultat comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: fixed , precision ) où precision est la précision spécifiée, ou 6 si la précision n'est pas spécifiée. -
g: Produit le résultat comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) où precision est la précision spécifiée, ou 6 si la précision n'est pas spécifiée. -
G: identique àg, sauf qu'il utiliseEpour indiquer l'exposant. - aucun : Si precision est spécifiée, produit le résultat comme en appelant std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) où precision est la précision spécifiée ; sinon, le résultat est produit comme en appelant std:: to_chars ( first, last, value ) .
Pour les types de présentation en minuscules, l'infini et NaN sont formatés respectivement comme
inf
et
nan
.
Pour les types de présentation en majuscules, l'infini et NaN sont formatés respectivement comme
INF
et
NAN
.
| std::format spécificateur | std::chars_format | spécificateur std::printf correspondant |
|---|---|---|
a
,
A
|
std::chars_format::hex |
a
,
A
(mais
std::format
ne génère pas les préfixes
0x
ou
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
|
| aucun | std::chars_format::general si la précision est spécifiée, sinon le format aller-retour le plus court |
g
si la précision est spécifiée. Sinon il n'y a pas de spécificateur correspondant.
|
Les types de présentation de pointeur disponibles (également utilisés pour std::nullptr_t ) sont :
-
none,
p: Si std::uintptr_t est défini, produit la sortie comme en appelant std:: to_chars ( first, last, reinterpret_cast < std:: uintptr_t > ( value ) , 16 ) avec le préfixe0xajouté à la sortie ; sinon, la sortie est définie par l'implémentation.
|
(depuis C++26) |
Formatage des caractères et chaînes échappésUn caractère ou une chaîne peut être formaté comme échappé pour le rendre plus adapté au débogage ou à la journalisation. L'échappement s'effectue comme suit :
La représentation échappée d'une chaîne est construite en échappant les séquences d'unités de code dans la chaîne, comme décrit ci-dessus, et en mettant le résultat entre guillemets doubles. La représentation échappée d'un caractère est construite en l'échappant comme décrit ci-dessus, et en mettant le résultat entre guillemets simples.
Exécuter ce 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: ["ẹ́"] } |
(depuis C++23) |
Notes
Dans la plupart des cas, la syntaxe est similaire à l'ancien formatage avec
%
, avec l'ajout des
{}
et en utilisant
:
à la place de
%
. Par exemple,
"%03.2f"
peut être traduit en
"{:03.2f}"
.
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_format_uchar
|
202311L
|
(C++20)
(DR) |
Formatage des unités de code en tant qu'entiers non signés |
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3721 | C++20 |
zéro n'est pas autorisé pour le champ de largeur
dans la spécification de format standard |
zéro est permis s'il est spécifié
via un champ de remplacement |
| P2909R4 | C++20 |
char
ou
wchar_t
pourraient être formatés comme
valeurs entières non signées hors plage |
les unités de code sont converties vers le type non signé
correspondant avant un tel formatage |