HOWTO · C++
Printing Boolean Values in C++
This article talks about printing textual representation of Boolean values in C++.
On this page
By default, C++ prints a Boolean value as 1 for true and 0 for false. That works for machines, but when you are scanning logs or debugging output, a lone 1 or 0 is easy to misread, while true and false tell the reader exactly what the program meant.
This article shows three ways to print Boolean values as text in C++: a conditional expression with printf, the std::boolalpha stream manipulator, and a custom std::numpunct facet for words other than true and false.
Why C++ prints Boolean values as 0 and 1
std::cout formats a bool through the same numeric machinery it uses for integers. Unless you change the stream’s formatting flags, true is written as 1 and false as 0. The printf family behaves similarly: a bool is promoted to int when passed through ..., so %d also prints 1 or 0.
Numeric output is compact, but a single digit disappears easily in a sea of numbers and log lines. Printing the words true and false makes program state self-describing, which is why each method below targets readable text.
Print Boolean text with printf and a conditional expression
printf has no Boolean format specifier, and the argument is promoted to int, so %d can only produce 1 or 0. The standard workaround is to switch the specifier to %s and select the text yourself with a conditional (ternary) expression: value ? "true" : "false".
The following program prints the same value both ways:
#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
This works anywhere printf is used and needs no stream state, but repeating the conditional at every call site adds noise in a large source file, and nothing enforces that the chosen strings stay consistent across calls.
Use std::boolalpha with C++ streams
std::boolalpha is a stream manipulator that sets the stream’s Boolean formatting flag so bool values print as true and false instead of 1 and 0. It works on input and output streams and is declared in <ios>, which <iostream> already includes.
Two properties matter in practice:
- The flag persists. Once you insert
std::boolalpha, every laterboolinserted into that stream prints as text until you change it back. std::noboolalphais the matching manipulator that restores the numeric representation.
The following program shows both states:
#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
Because the flag persists on the stream, remember it applies to every bool printed afterward — insert std::noboolalpha when later output should stay numeric. Also note that std::boolalpha only produces the locale’s names for the two values, by default true and false. For different words you need the facet approach in the next section.
Customize Boolean text with a std::numpunct facet
The words a stream uses for true and false come from the std::numpunct facet of the stream’s locale. Stream output operations go through std::numput, which asks that facet for the Boolean names via its do_truename() and do_falsename() members. Deriving your own facet and imbuing the stream with a locale that contains it replaces those names while std::boolalpha is active.
The following program installs a facet that supplies its own words:
#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
The strings Hai and NAI are literals supplied by the facet itself — nothing is translated automatically; the stream simply prints whatever do_truename() and do_falsename() return. The new named_bool allocation does not leak either: facet objects are reference-counted and are destroyed when the last std::locale that references them goes out of scope.
This approach only takes effect while std::boolalpha is set; without it the stream still prints 1 and 0. It is also the most machinery of the three — a derived class, two overrides, and an imbue call — so reserve it for cases where custom wording is the actual requirement.
Choose the right approach
- For one or two values in C-style code,
printfwithvalue ? "true" : "false"is the smallest change, but it repeats the selection logic at every call site. - For iostream output,
std::boolalphais the idiomatic fix; pair it withstd::noboolalphawhen laterbooloutput should return to1/0. - When the words themselves must change — capitalization like
True/Falseor a custom pair such asHai/NAI— astd::numpunctfacet plus an imbued locale is the only option of the three, since it redefines whatstd::boolalphaprints.
Pick the simplest tool that covers your formatting need: a conditional expression for a single value, std::boolalpha for stream output, and a facet only when custom Boolean names are required.