Skip to main content

Raymii.org Raymii.org Logo

Quis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed | Gopher

Three ways to print booleans as 'True' or 'False' in C++

Published: 21-03-2021 | Author: Remy van Elst | Text only version of this article


Table of Contents


In this article I'll show you three ways to print a textual representation of a boolean in C++. Normally a bool is printed as either a 0 or a 1 by std::cout, but more often than not, if you're printing a bool, it's better to see true/false. Imagine reading through lines and lines of boring, repeating log files, how easy is it to miss a 0 in a sea of 1's? I've been there many times, wishing for more verbose logs. I'll start with a simple printf with a ternary if e.g. (a ? this : that) and continue on to std::boolalpha. The latter one is more flexible and allows you to set different values to be printed, for localization, and can even be used to parse input streams. That means, the string true false results in two booleans, the first being, well, true and the latter, surprisingly, being false.

Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.

You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days.

clang-tidy wasn't having any of it when I was working on the code examples for this article:

screenshot

Reminds me of this comic from CommitStrip, I'm watching you!:

comic

printf with a ternary if

The simplest solution, just using good old printf. For your one off logging statement, or poor mans debugging, probably just fine.

If you pass a bool to printf, you must use %d as the format specifier. There isn't one for bool's, but %d works because any integral type shorter than int is promoted to int when passed to printf()'s variadic arguments:

printf("printf true : %d\n", true);
printf("printf false: %d\n", false);

Output:

printf true : 1
printf false: 0

Add a ternary if statement and change the format specifier to %s and, as if it were magic, true or false ends up on your terminal:

printf("printf if true : %s\n", true ? "true" : "false");
printf("printf if false: %s\n", false ? "true" : "false");

Output:

printf if true : true
printf if false: false

On a personal note, I dislike these ternary if, also called shorthand if, statements. They do not help for readability and I'm a firm believer that code is meant to be read by other programmers, not by compilers, so readability is a big thing. Shorthand if's might save a few characters, but boy do I dislike them.

std::boolalpha

std::boolalpha works with the input and output stream functions and can be found in the <iomanip> header. Use is simple, if you're familiar with std::setprecision or std::setw, this is basically the same.

Printing a bool without the I/O manipulator active results in just 0/1:

std::cout << "boolalpha off true : " << true << "\n" <<
             "boolalpha off false: " << false << "\n";

Output:

boolalpha off true : 1
boolalpha off false: 0

Adding std::boolalpha to your output stream will by default print true/false:

std::cout << std::boolalpha
          << "boolalpha on true  : " << true << "\n"
          << "boolalpha on false : " << false << "\n"
          << std::noboolalpha;

Output:

boolalpha on true  : true
boolalpha on false : false

As you can see you must also turn the flag off (via std::noboolalpha). But what if you code in Dutch, or any other language, and want to have Waar or Onwaar printed instead of true and false? Or even simpler, just capitalize the words, True and False? Well dear reader, continue on to the next paragraph where I'll cover all facets of std::numpunct.

Something other than true or false?

As we just said in the previous paragraph, what if you want to print something other than true or false? Localized or capitalized output? You can define a custom facet for std::numpunct. A facet is a class describing a locale feature set associated to a specific cultural aspect.

The facet std::numpunct encapsulates numeric punctuation preferences. Stream I/O operations use std::numpunct through std::numget and std::numput for parsing numeric input and formatting numeric output.

One thins to note is that as of writing this article, std::locale::facet use their own method for reference counting. Not unlike a std::shared_ptr, but not exactly the same either. In the below example you'll

By overriding the functions do_truename() and do_falsename() in std::numpunct you can specify which strings are returned when std::boolalpha is active. After that, you use std::cout.imbue() with a std::locale object to replace the current locale.

Below is an example:

#include <string>
#include <iostream>
#include <locale> //numpunct
#include <ios> //boolalpha

class dutch_bool : public std::numpunct< char > {
protected:
    std::string do_truename() const override { return "Waar";  }
    std::string do_falsename() const override { return "Onwaar"; }
};

int main() {

    // new is not a memory leak here, the dutch_bool object is
    // implicitly reference counted and it will be destroyed
    // when the last std::locale referencing it goes out of scope.
    std::cout.imbue(std::locale(std::locale(), new dutch_bool));

    std::cout << std::boolalpha
              << "NL boolalpha true  : " << true << "\n"
              << "NL boolalpha false : " << false << "\n"
              << std::noboolalpha;


    return 0;
}

Output:

NL boolalpha true  : Waar
NL boolalpha false : Onwaar
Tags: articles , c++ , cpp , development , localization , printf