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.

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 later bool inserted into that stream prints as text until you change it back.
  • std::noboolalpha is 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, printf with value ? "true" : "false" is the smallest change, but it repeats the selection logic at every call site.
  • For iostream output, std::boolalpha is the idiomatic fix; pair it with std::noboolalpha when later bool output should return to 1/0.
  • When the words themselves must change — capitalization like True/False or a custom pair such as Hai/NAI — a std::numpunct facet plus an imbued locale is the only option of the three, since it redefines what std::boolalpha prints.

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.