This is a text-only version of the following page on https://raymii.org:
---
Title       : 	Three ways to print booleans as 'True' or 'False' in C++
Author      : 	Remy van Elst
Date        : 	21-03-2021
URL         : 	https://raymii.org/s/articles/Print_booleans_as_True_or_False_in_C++.html
Format      : 	Markdown/HTML
---



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`.

<p class="ad"> <b>Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:</b><br><br> <a href="https://leafnode.nl">I'm developing an open source monitoring app called  Leaf Node Monitoring, for windows, linux & android. Go check it out!</a><br><br> <a href="https://github.com/sponsors/RaymiiOrg/">Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.</a><br><br> <a href="https://www.digitalocean.com/?refcode=7435ae6b8212">You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days. </a><br><br> </p>


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

![screenshot][3]

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

![comic][5]



### 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][2] 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][2] [facets][6] 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`][6] for [`std::numpunct`][1].  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::num_get and std::num_put 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][6]. 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][1] 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][7].

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




[1]: https://en.cppreference.com/w/cpp/locale/numpunct
[2]: https://en.cppreference.com/w/cpp/io/manip/boolalpha
[3]: /s/inc/img/cpp_bool_clang_tidy.png
[4]: https://www.commitstrip.com/en/2020/06/11/im-watching-you/?
[5]: /s/inc/img/Strip-Visual-Studio-Code-650-finalenglish.jpg
[6]: https://en.cppreference.com/w/cpp/locale/locale/facet/facet
[7]: https://en.cppreference.com/w/cpp/io/basic_ios/imbue


---

License:
All the text on this website is free as in freedom unless stated otherwise. 
This means you can use it in any way you want, you can copy it, change it 
the way you like and republish it, as long as you release the (modified) 
content under the same license to give others the same freedoms you've got 
and place my name and a link to this site with the article as source.

This site uses Google Analytics for statistics and Google Adwords for 
advertisements. You are tracked and Google knows everything about you. 
Use an adblocker like ublock-origin if you don't want it.

All the code on this website is licensed under the GNU GPL v3 license 
unless already licensed under a license which does not allows this form 
of licensing or if another license is stated on that page / in that software:

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Just to be clear, the information on this website is for meant for educational 
purposes and you use it at your own risk. I do not take responsibility if you 
screw something up. Use common sense, do not 'rm -rf /' as root for example. 
If you have any questions then do not hesitate to contact me.

See https://raymii.org/s/static/About.html for details.