Die Formatierungsbibliothek in C++20: Details zum Formatstring
(Bild: DirtyMono/Shutterstock)
Der zweite Teil der Serie zu Formatstrings in C++20 beschÀftigt sich mit der Breite, der Genauigkeit und dem Datentyp der Formatspezifikation.
In meinem letzten Artikel "Die Formatierungsbibliothek in C++20: Der Formatstring [1]" habe ich einige der Formatspezifikationen des Formatstrings vorgestellt. Heute beende ich die Abhandlung dazu.
Im heutigen Artikel werde ich ĂŒber die Breite, die Genauigkeit und den Datentyp der Formatspezifikation schreiben. Wenn Du mehr ĂŒber das Argument id, die FĂŒllzeichen, die Ausrichtung, die Vorzeichen und die alternative Form wissen willst, lies meinen vorherigen Artikel: "Die Formatierungsbibliothek in C++20: Der Formatstring [2]".
Breite und Genauigkeit
Man kann die Breite und die Genauigkeit eines Arguments angeben. Die Breite kann auf Zahlen und die Genauigkeit auf FlieĂkommazahlen und Zeichenketten angewendet werden. Bei FlieĂkommazahlen gibt die Genauigkeit die Formatierungsgenauigkeit an; bei Zeichenketten gibt die Genauigkeit an, wie viele Zeichen verwendet werden und wie die Zeichenkette letztendlich abgeschnitten wird. Wenn die Genauigkeit gröĂer ist als die LĂ€nge der Zeichenkette, hat dies keine Auswirkungen auf die Zeichenkette.
- Breite: Man kann entweder eine positive Dezimalzahl oder ein Ersetzungsfeld (
{}oder{n}) verwenden. Wenn angegeben, gibtndie Mindestbreite an. - Genauigkeit: Man kann einen Punkt (.) gefolgt von einer nicht-negativen Dezimalzahl oder ein Ersetzungsfeld verwenden.
Ein paar Beispiele sollen helfen, die Grundlagen zu verstehen:
// formatWidthPrecision.cpp
#include <format>
#include <iostream>
#include <string>
int main() {
int i = 123456789;
double d = 123.456789;
std::cout << "---" << std::format("{}", i) << "---\n";
std::cout << "---" << std::format("{:15}", i)
<< "---\n"; // (w = 15)
std::cout << "---" << std::format("{:}", i)
<< "---\n"; // (w = 15) // (1)
std::cout << '\n';
std::cout << "---" << std::format("{}", d) << "---\n";
std::cout << "---" << std::format("{:15}", d)
<< "---\n"; // (w = 15)
std::cout << "---" << std::format("{:}", d)
<< "---\n"; // (w = 15)
std::cout << '\n';
std::string s= "Only a test";
std::cout << "---" << std::format("{:10.50}", d)
<< "---\n"; // (w = 10, p = 50) // (2)
std::cout << "---" << std::format("{:{}.{}}", d, 10, 50)
<< "---\n"; // (w = 10, p = 50) // (3)
std::cout << "---" << std::format("{:10.5}", d)
<< "---\n"; // (w = 10, p = 5)
std::cout << "---" << std::format("{:{}.{}}", d, 10, 5)
<< "---\n"; // (w = 10, p = 5)
std::cout << '\n';
std::cout << "---" << std::format("{:.500}", s)
<< "---\n"; // (p = 500) // (4)
std::cout << "---" << std::format("{:.{}}", s, 500)
<< "---\n"; // (p = 500) // (5)
std::cout << "---" << std::format("{:.5}", s)
<< "---\n"; // (p = 5)
}
Das w-Zeichen im Quellcode steht fĂŒr die Breite; ebenso das p-Zeichen fĂŒr die Genauigkeit.
Hier sind ein paar interessante Beobachtungen zu dem Programm: Es werden keine zusĂ€tzlichen Leerzeichen hinzugefĂŒgt, wenn die Breite mit einem Ersetzungsfeld angegeben wird (1). Wenn eine Genauigkeit verwendet wird, die gröĂer ist, als die LĂ€nge des angezeigten double (2 und 3), spiegelt die LĂ€nge des angezeigten Wertes die Genauigkeit wider. Diese Beobachtung gilt nicht fĂŒr eine Zeichenkette (4 und 5).
ZusÀtzlich lÀsst sich die Breite und die Genauigkeit parametrisieren.
// formatWidthPrecisionParametrized.cpp
#include <format>
#include <iostream>
int main() {
std::cout << '\n';
double doub = 123.456789;
std::cout << std::format("{:}\n", doub); // (1)
std::cout << '\n';
for (auto precision: {3, 5, 7, 9}) {
std::cout << std::format("{:.{}}\n",
doub,
precision); // (2)
}
std::cout << '\n';
int width = 10;
for (auto precision: {3, 5, 7, 9}) {
std::cout << std::format("{:{}.{}}\n",
doub,
width,
precision); // (3)
}
std::cout << '\n';
Das Programm formatWidthPrecisionParametrized.cpp stellt das Double doub auf verschiedene Arten dar. (1) wendet die Standardeinstellung an. (2) variiert die Genauigkeit von 3 bis 9. Das letzte Argument des Formatstrings geht in das innere {} des Formatspezifiers {:.{}}. SchlieĂlich wird in (3) die Breite der angezeigten Double-Werte auf 10 gesetzt.
Datentyp
Im Allgemeinen leitet der Compiler den Typ des verwendeten Wertes ab. Aber manchmal möchte man den Datentyp angeben. Dies sind die wichtigsten Datentypen:
Zeichenketten: s
Ganzzahlen:
b: BinÀrformatB: wieb, aber BasisprÀfix ist0Bd: dezimales Formato: oktales Formatx:hexadezimales FormatX: wiex, aber das BasisprÀfix ist0X
char und wchar_t:
b, B, d, o, x, X: wie Ganzzahlen
bool:
s:trueoderfalseb, B, d, o, x, X: wie Ganzzahlen
FlieĂkommazahlen:
e: ExponentialformatE: wiee, aber der Exponent wird mitEgeschriebenf, F: Festkomma; die Genauigkeit betrÀgt 6g, G: Genauigkeit 6, aber der Exponent wird mitEgeschrieben
Zeiger:
p: hexadezimale Schreibweise seiner Adresse
Nur die Datentypen void, const void und std::nullptr_t sind gĂŒltig. Wer die Adresse eines beliebigen Zeigers anzeigen will, muss ihn in (const) void* umwandeln.
double d = 123.456789;
std::format("{}", &d); // ERROR
std::format("{}", static_cast<void*>(&d)); // okay
std::format("{}", static_cast<const void*>(&d)); // okay
std::format("{}", nullptr); // okay
Mit den Datentypen kann man einen int ganz einfach in einem anderen Zahlensystem darstellen.
// formatType.cpp
#include <format>
#include <iostream>
int main() {
int num{2020};
std::cout << "default: " << std::format("{:}", num)
<< '\n';
std::cout << "decimal: " << std::format("{:d}", num)
<< '\n';
std::cout << "binary: " << std::format("{:b}", num)
<< '\n';
std::cout << "octal: " << std::format("{:o}", num)
<< '\n';
std::cout << "hexadecimal: " << std::format("{:x}", num)
<< '\n';
}
Wie geht es weiter?
Bisher habe ich die elementaren Datentypen und Strings formatiert. NatĂŒrlich lassen sich auch benutzerdefinierte Typen formatieren. Das wird das Thema meines nĂ€chsten Artikels sein. (rme [3])
URL dieses Artikels:
https://www.heise.de/-9615593
Links in diesem Artikel:
[1] https://www.heise.de/blog/Die-Formatierungsbibliothek-in-C-20-Der-Formatstring-9610546.html
[2] https://www.heise.de/blog/Die-Formatierungsbibliothek-in-C-20-Der-Formatstring-9610546.html
[3] mailto:rme@ix.de
Copyright © 2024 Heise Medien