HOWTO · C++
Drucken boolescher Werte in C++
Dieser Artikel behandelt das Drucken von Textdarstellungen von booleschen Werten in C++.
Auf dieser Seite
Standardmäßig gibt C++ einen booleschen Wert als 1 für true und 0 für false aus. Für Maschinen ist das ausreichend, aber beim Durchsehen von Logs oder Debugging-Ausgaben wird eine einzelne 1 oder 0 leicht übersehen, während true und false dem Leser genau sagen, was das Programm gemeint hat.
Dieser Artikel zeigt drei Möglichkeiten, boolesche Werte in C++ als Text auszugeben: einen bedingten Ausdruck mit printf, den Stream-Manipulator std::boolalpha und eine benutzerdefinierte std::numpunct-Facette für andere Wörter als true und false.
Warum C++ boolesche Werte als 0 und 1 ausgibt
std::cout formatiert ein bool über denselben numerischen Mechanismus, den es auch für Ganzzahlen verwendet. Solange Sie die Formatierungsflags des Streams nicht ändern, wird true als 1 und false als 0 geschrieben. Die printf-Familie verhält sich ähnlich: Ein bool wird bei der Übergabe über ... zu int heraufgestuft, sodass %d ebenfalls 1 oder 0 ausgibt.
Die numerische Ausgabe ist kompakt, aber eine einzelne Ziffer geht in einem Meer von Zahlen und Logzeilen leicht unter. Gibt man die Wörter true und false aus, wird der Programmzustand selbstbeschreibend – deshalb zielt jede der folgenden Methoden auf lesbaren Text ab.
Booleschen Text mit printf und einem bedingten Ausdruck ausgeben
printf kennt keinen booleschen Formatbezeichner, und das Argument wird zu int heraufgestuft, sodass %d nur 1 oder 0 erzeugen kann. Der übliche Ausweg besteht darin, zum Bezeichner %s zu wechseln und den Text selbst mit einem bedingten (ternären) Ausdruck auszuwählen: value ? "true" : "false".
Das folgende Programm gibt denselben Wert auf beide Arten aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
#include <cstdio>
int main() {
bool ready = true;
std::printf("numeric: %d\n", ready);
std::printf("text: %s\n", ready ? "true" : "false");
std::printf("text: %s\n", false ? "true" : "false");
return 0;
}
numeric: 1
text: true
text: false
Das funktioniert überall, wo printf verwendet wird, und benötigt keinen Stream-Zustand. Allerdings erzeugt die Wiederholung des bedingten Ausdrucks an jeder Aufrufstelle in einer großen Quelldatei unnötiges Rauschen, und nichts stellt sicher, dass die gewählten Strings über alle Aufrufe hinweg konsistent bleiben.
std::boolalpha mit C++-Streams verwenden
std::boolalpha ist ein Stream-Manipulator, der das boolesche Formatierungsflag des Streams setzt, sodass bool-Werte als true und false statt als 1 und 0 ausgegeben werden. Er funktioniert mit Eingabe- und Ausgabestreams und ist in <ios> deklariert, das <iostream> bereits einbindet.
Zwei Eigenschaften sind in der Praxis wichtig:
- Das Flag bleibt bestehen. Sobald Sie
std::boolalphaeingefügt haben, wird jedes weiterebool, das in diesen Stream geschrieben wird, als Text ausgegeben, bis Sie es zurücksetzen. std::noboolalphaist der zugehörige Manipulator, der die numerische Darstellung wiederherstellt.
Das folgende Programm zeigt beide Zustände:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
#include <iostream>
int main() {
std::cout << "default: " << true << " / " << false << "\n";
std::cout << std::boolalpha;
std::cout << "boolalpha: " << true << " / " << false << "\n";
std::cout << std::noboolalpha;
std::cout << "restored: " << true << " / " << false << "\n";
return 0;
}
default: 1 / 0
boolalpha: true / false
restored: 1 / 0
Da das Flag im Stream bestehen bleibt, denken Sie daran, dass es für jedes danach ausgegebene bool gilt – fügen Sie std::noboolalpha ein, wenn spätere Ausgaben numerisch bleiben sollen. Beachten Sie außerdem, dass std::boolalpha nur die Namen des Gebietsschemas für die beiden Werte erzeugt, standardmäßig true und false. Für andere Wörter benötigen Sie den Facetten-Ansatz aus dem nächsten Abschnitt.
Booleschen Text mit einer std::numpunct-Facette anpassen
Die Wörter, die ein Stream für true und false verwendet, stammen aus der std::numpunct-Facette des Gebietsschemas des Streams. Stream-Ausgabeoperationen laufen über std::numput, das die booleschen Namen über die Member do_truename() und do_falsename() dieser Facette abfragt. Wenn Sie eine eigene Facette ableiten und den Stream mit einem Gebietsschema versehen, das sie enthält, werden diese Namen ersetzt, solange std::boolalpha aktiv ist.
Das folgende Programm installiert eine Facette, die eigene Wörter liefert:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
#include <iostream>
#include <locale>
#include <string>
class named_bool : public std::numpunct<char> {
protected:
std::string do_truename() const override { return "Hai"; }
std::string do_falsename() const override { return "NAI"; }
};
int main() {
std::cout.imbue(std::locale(std::locale(), new named_bool));
std::cout << std::boolalpha;
std::cout << "custom true: " << true << "\n";
std::cout << "custom false: " << false << "\n";
return 0;
}
custom true: Hai
custom false: NAI
Die Strings Hai und NAI sind Literale, die von der Facette selbst geliefert werden – nichts wird automatisch übersetzt; der Stream gibt einfach aus, was do_truename() und do_falsename() zurückgeben. Auch die new named_bool-Allokation erzeugt kein Speicherleck: Facettenobjekte sind referenzgezählt und werden zerstört, sobald das letzte std::locale, das sie referenziert, den Gültigkeitsbereich verlässt.
Dieser Ansatz wirkt nur, solange std::boolalpha gesetzt ist; ohne ihn gibt der Stream weiterhin 1 und 0 aus. Er ist außerdem der aufwendigste der drei – eine abgeleitete Klasse, zwei Überschreibungen und ein imbue-Aufruf – also reservieren Sie ihn für Fälle, in denen eine eigene Wortwahl tatsächlich erforderlich ist.
Den richtigen Ansatz wählen
- Für ein oder zwei Werte in C-artigem Code ist
printfmitvalue ? "true" : "false"die kleinste Änderung, wiederholt aber die Auswahllogik an jeder Aufrufstelle. - Für iostream-Ausgaben ist
std::boolalphadie idiomatische Lösung; kombinieren Sie ihn mitstd::noboolalpha, wenn späterebool-Ausgaben wieder zu1/0zurückkehren sollen. - Wenn die Wörter selbst geändert werden müssen – etwa Großschreibung wie
True/Falseoder ein eigenes Paar wieHai/NAI– ist einestd::numpunct-Facette plus einem zugewiesenen Gebietsschema die einzige der drei Optionen, da sie neu definiert, wasstd::boolalphaausgibt.
Wählen Sie das einfachste Werkzeug, das Ihren Formatierungsbedarf abdeckt: einen bedingten Ausdruck für einen einzelnen Wert, std::boolalpha für Stream-Ausgaben und eine Facette nur dann, wenn benutzerdefinierte boolesche Namen erforderlich sind.