This is a text-only version of the following page on --- Title : Three ways to print booleans as 'True' or 'False' in C++ Author : Remy van Elst Date : 21-03-2021 URL : 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`.



`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 `` 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 #include #include //numpunct #include //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]: [2]: [3]: /s/inc/img/cpp_bool_clang_tidy.png [4]: [5]: /s/inc/img/Strip-Visual-Studio-Code-650-finalenglish.jpg [6]: [7]: --- 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 . Just to be clear, the information on this website is for ment 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 for details.