Converting bool to text in C++
Asked Answered
T

17

124

Maybe this is a dumb question, but is there any way to convert a boolean value to a string such that 1 turns to "true" and 0 turns to "false"? I could just use an if statement, but it would be nice to know if there is a way to do that with the language or standard libraries. Plus, I'm a pedant. :)

Twig answered 27/8, 2008 at 2:32 Comment(2)
Objection! What about localization? Why would a language itself contain language-specific literal constants?Lunkhead
@Lunkhead - I'm pretty sure that for the project I was working on, internationalization wasn't a concern. At the time, it was likely a school project.Twig
K
142

How about using the C++ language itself?

bool t = true;
bool f = false;
std::cout << std::noboolalpha << t << " == " << std::boolalpha << t << std::endl;        
std::cout << std::noboolalpha << f << " == " << std::boolalpha << f << std::endl;

UPDATE:

If you want more than 4 lines of code without any console output, please go to cppreference.com's page talking about std::boolalpha and std::noboolalpha which shows you the console output and explains more about the API.

Additionally using std::boolalpha will modify the global state of std::cout, you may want to restore the original behavior go here for more info on restoring the state of std::cout.

Khanate answered 27/8, 2008 at 5:10 Comment(11)
I'm a complete newbie to C++. Can somebody explain to me how this works?Sind
@Sind You won't be able to understand how this works until you understand operator overloading. Explaining how that works would be far beyond the scope of this question. You'll need to either post it as a different question, or look up existing answers to that question. I recommend the latter.Tribal
This only prints booleans as text, it doesn't convert them to text/string.Wither
So in what way does this fail the "to convert a boolean value to a string" criteria given by the OP?Khanate
This solution is too slow for C++.Streit
The OP didn't ask for a perfomant version. And I didn't know C++ has a minimum performance criteria for iostream.Khanate
This code does not convert a boolean to a string. Create a variable std::string str and save the result of the conversion into it, if you can.Extrauterine
@Extrauterine It converts it to a stream of characters which can easily be saved into a string.Khanate
Don't you have to cast your value to (bool). Otherwise, the compiler may complain with an error: invalid operands of types 'const charMyke
@CrazyVideoGamez Which part are you having trouble with?Khanate
@CrazyVideoGamez If you want to display a bool as text you can use the manipulator std::boolalpha to display the bool as a textual representation. Eg: 1 is displayed as true. To turn off the manipulator you use std::noboolalpha. If you want to display the boolean as something other than true or false (on or off for example) you can use do_truename and do_falsename respectively.Khanate
D
105

We're talking about C++ right? Why on earth are we still using macros!?

C++ inline functions give you the same speed as a macro, with the added benefit of type-safety and parameter evaluation (which avoids the issue that Rodney and dwj mentioned.

inline const char * const BoolToString(bool b)
{
  return b ? "true" : "false";
}

Aside from that I have a few other gripes, particularly with the accepted answer :)

// this is used in C, not C++. if you want to use printf, instead include <cstdio>
//#include <stdio.h>
// instead you should use the iostream libs
#include <iostream>

// not only is this a C include, it's totally unnecessary!
//#include <stdarg.h>

// Macros - not type-safe, has side-effects. Use inline functions instead
//#define BOOL_STR(b) (b?"true":"false")
inline const char * const BoolToString(bool b)
{
  return b ? "true" : "false";
}

int main (int argc, char const *argv[]) {
    bool alpha = true;

    // printf? that's C, not C++
    //printf( BOOL_STR(alpha) );
    // use the iostream functionality
    std::cout << BoolToString(alpha);
    return 0;
}

Cheers :)


@DrPizza: Include a whole boost lib for the sake of a function this simple? You've got to be kidding?

Dachy answered 27/8, 2008 at 9:34 Comment(8)
@NathanFellman, the accepted answer is too slow. This one can be improved for string if string constants for "true" and "false" are stored in static const variables.Streit
This is a problematic answer, since: 1. Sometimes you want "yes" or "no" rather than "true or "false", and sometimes "success" vs "failure" etc. 2. Sometimes you want lower case, sometime upper case, sometime title case.Kehr
Read the question, it's exactly what was requested.Dachy
@Kehr Nothing is stopping you from creating as many inline functions for your desired conversions as you want.Extrauterine
in a crunch you can do: cout << (bool_x ? "true": "false") << endl;Eh
Macros are way waaaaay faster than inlines when it comes to a one-liner code.Teatime
@Teatime no, no they are not. A Macro simply replaces that part of the sourcecode. An inline-function, if as trivial as the macro, will also be substituted in place and not add any function-calls, conversions or anything else, but with the benefit of type-safety.Mali
@Kehr this is what OP wanted, and if you really wanted to change the true or false to something else, just change the code. You could also have extra arguments for more functionalityFutrell
C
21

C++ has proper strings so you might as well use them. They're in the standard header string. #include <string> to use them. No more strcat/strcpy buffer overruns; no more missing null terminators; no more messy manual memory management; proper counted strings with proper value semantics.

C++ has the ability to convert bools into human-readable representations too. We saw hints at it earlier with the iostream examples, but they're a bit limited because they can only blast the text to the console (or with fstreams, a file). Fortunately, the designers of C++ weren't complete idiots; we also have iostreams that are backed not by the console or a file, but by an automatically managed string buffer. They're called stringstreams. #include <sstream> to get them. Then we can say:

std::string bool_as_text(bool b)
{
    std::stringstream converter;
    converter << std::boolalpha << b;   // flag boolalpha calls converter.setf(std::ios_base::boolalpha)
    return converter.str();
}

Of course, we don't really want to type all that. Fortunately, C++ also has a convenient third-party library named Boost that can help us out here. Boost has a nice function called lexical_cast. We can use it thus:

boost::lexical_cast<std::string>(my_bool)

Now, it's true to say that this is higher overhead than some macro; stringstreams deal with locales which you might not care about, and create a dynamic string (with memory allocation) whereas the macro can yield a literal string, which avoids that. But on the flip side, the stringstream method can be used for a great many conversions between printable and internal representations. You can run 'em backwards; boost::lexical_cast<bool>("true") does the right thing, for example. You can use them with numbers and in fact any type with the right formatted I/O operators. So they're quite versatile and useful.

And if after all this your profiling and benchmarking reveals that the lexical_casts are an unacceptable bottleneck, that's when you should consider doing some macro horror.

Crowell answered 27/8, 2008 at 9:56 Comment(3)
boost::lexical_cast<bool>("true") seems to throw a bad_lexical_cast exceptionWendolyn
not work in my app, "isExist: "+boost::lexical_cast<std::string>(isExit)); results isExist: 0Jacquez
Keep an eye to performanceCarlyn
R
11

This should be fine:


const char* bool_cast(const bool b) {
    return b ? "true" : "false";
}

But, if you want to do it more C++-ish:


#include <iostream>
#include <string>
#include <sstream>
using namespace std;

string bool_cast(const bool b) {
    ostringstream ss;
    ss << boolalpha << b;
    return ss.str();
}

int main() {
    cout << bool_cast(true) << "\n";
    cout << bool_cast(false) << "\n";
}
Rightful answered 27/8, 2008 at 11:8 Comment(0)
A
7

C++20 std::format("{}"

https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification claims that the default output format will be the string by default:

#include <format>
auto s6 = std::format("{:6}", true);  // value of s6 is "true  "

and:

The available bool presentation types are:

  • none, s: Copies textual representation (true or false, or the locale-specific form) to the output.
  • b, B, c, d, o, x, X: Uses integer presentation types with the value static_cast(value).

The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:

sudo apt install libfmt-dev

Modify source to replace:

  • <format> with <fmt/core.h>
  • std::format to fmt::format

main.cpp

#include <string>
#include <iostream>

#include <fmt/core.h>

int main() {
    std::string message = fmt::format("The {} answer is {}.", true, false);
    std::cout << message << std::endl;
}

and compile and run with:

g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out

Output:

The true answer is false.

Related: std::string formatting like sprintf

Arel answered 10/11, 2020 at 15:33 Comment(0)
M
4

If you decide to use macros (or are using C on a future project) you should add parenthesis around the 'b' in the macro expansion (I don't have enough points yet to edit other people's content):

#define BOOL_STR(b) ((b)?"true":"false")

This is a defensive programming technique that protects against hidden order-of-operations errors; i.e., how does this evaluate for all compilers?

1 == 2 ? "true" : "false"

compared to

(1 == 2) ? "true" : "false"
Millett answered 27/8, 2008 at 4:46 Comment(1)
Even before having de 2k rep you actually could edit other people's content. It will be reviewed, but of course you could.Wacky
J
4

A really quick and clean solution, if you're only doing this once or don't want to change the global settings with bool alpha, is to use a ternary operator directly in the stream, like so:

bool myBool = true;
std::cout << "The state of myBool is: " << (myBool ? "true" : "false") << std::endl;
enter code here

Ternarys are easy to learn. They're just an IF statement on a diet, that can be dropped pretty well anywhere, and:

(myBool ? "true" : "false")

is pretty well this (sort of):

{
   if(myBool){
      return "true";
   } else {
      return "false";
   }
}

You can find all kinds of fun uses for ternarys, including here, but if you're always using them to output a "true" "false" into the stream like this, you should just turn the boolalpha feature on, unless you have some reason not to:

std::cout << std::boolalpha;

somewhere at the top of your code to just turn the feature on globally, so you can just drop those sweet sweet booleans right into the stream and not worry about it.

But don't use it as a tag for one-off use, like this:

std::cout << "The state of myBool is: " << std::boolalpha << myBool << std::noboolalpha;

That's a lot of unnecessary function calls and wasted performance overhead and for a single bool, when a simple ternary operator will do.

Jarib answered 4/5, 2021 at 4:37 Comment(0)
A
3

I use a ternary in a printf like this:

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

If you macro it :

B2S(b) ((b)?"true":"false")

then you need to make sure whatever you pass in as 'b' doesn't have any side effects. And don't forget the brackets around the 'b' as you could get compile errors.

Adrianeadrianna answered 27/8, 2008 at 4:19 Comment(1)
As 'b' only shows up once in the macro definition, why are you warning of side effects?Weaponless
S
2

With C++11 you might use a lambda to get a slightly more compact code and in place usage:

bool to_convert{true};
auto bool_to_string = [](bool b) -> std::string {
    return b ? "true" : "false";
};
std::string str{"string to print -> "};
std::cout<<str+bool_to_string(to_convert);

Prints:

string to print -> true
Saleh answered 13/12, 2018 at 13:50 Comment(0)
I
2

Without dragging ostream into it:

constexpr char const* to_c_str(bool b) {
   return  
    std::array<char const*, 2>{"false", "true "}[b]
   ;
};
Intermittent answered 3/8, 2019 at 10:35 Comment(0)
P
1

Use boolalpha to print bool to string.

std::cout << std::boolalpha << b << endl;
std::cout << std::noboolalpha << b << endl;

C++ Reference

Proclus answered 22/5, 2018 at 12:52 Comment(0)
S
0

This post is old but now you can use std::to_string to convert a lot of variable as std::string.

http://en.cppreference.com/w/cpp/string/basic_string/to_string

Sheathing answered 28/2, 2018 at 14:56 Comment(1)
You can but if you do this on a bool variable it will just convert the numeric value, "1" or "0", rather than "true" or "false".Cyrenaic
P
0

How about the simple:

constexpr char const* toString(bool b)
{
   return b ? "true" : "false";
}
Pyemia answered 18/8, 2020 at 12:2 Comment(0)
C
-2
#include <iostream>
#include <string>

using namespace std;

string toBool(bool boolean)
{
    string result;
    if(boolean == true)
        result = "true";
    else 
        result = "false";
    return result;
}   

int main()
{
     bool myBoolean = true;          //Boolean
     string booleanValue;
     booleanValue = toBool(myBoolean);
     cout << "bool: " << booleanValue << "\n";
 }
Coopery answered 25/8, 2022 at 8:25 Comment(0)
S
-3

I agree that a macro might be the best fit. I just whipped up a test case (believe me I'm no good with C/C++ but this sounded fun):

#include <stdio.h>
#include <stdarg.h>

#define BOOL_STR(b) (b?"true":"false")

int main (int argc, char const *argv[]) {
    bool alpha = true;
    printf( BOOL_STR(alpha) );
    return 0;
}
Sinistrous answered 27/8, 2008 at 2:41 Comment(0)
N
-6

As long as strings can be viewed directly as a char array it's going to be really hard to convince me that std::string represents strings as first class citizens in C++.

Besides, combining allocation and boundedness seems to be a bad idea to me anyways.

Nathannathanael answered 27/8, 2008 at 13:37 Comment(0)
D
-7

Try this Macro. Anywhere you want the "true" or false to show up just replace it with PRINTBOOL(var) where var is the bool you want the text for.

#define PRINTBOOL(x) x?"true":"false"
Delila answered 27/8, 2008 at 2:42 Comment(1)
Need some parentheses in that macro, which is probably why you got the downvote.Weaponless

© 2022 - 2024 — McMap. All rights reserved.