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. :)
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.
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?
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.
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";
}
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
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"
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.
Without dragging ostream into it:
constexpr char const* to_c_str(bool b) {
return
std::array<char const*, 2>{"false", "true "}[b]
;
};
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
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.
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
Use boolalpha to print bool to string.
std::cout << std::boolalpha << b << endl;
std::cout << std::noboolalpha << b << endl;
C++ Reference
How about the simple:
constexpr char const* toString(bool b)
{
return b ? "true" : "false";
}
#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";
}
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;
}
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.
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"
Related
I'm compiling the following program using Microsoft Visual C++, as a C++20 program:
#include <iostream>
#include <tuple>
int main()
{
auto t1 = std::make_tuple("one", "two", "three");
auto t2 = std::make_tuple("one", "two", "three");
std::cout << "(t1 == t2) is " << std::boolalpha << (t1 == t2) << "\n";
std::cout << "(t1 != t2) is " << std::boolalpha << (t1 != t2) << "\n";
return 0;
}
When I run it, I see the following output:
(t1 == t2) is false
(t1 != t2) is true
The tuples are identical, so why does it have wrong comparison results? How do I fix this?
You are comparing pointers to buffers of characters, not strings.
Sometimes the compiler will turn two different "one"s into the same buffer, sometimes it will not.
In your case, it isn't. Probably a debug build.
Add #include <string_view>, then
using namespace std::literals;
auto t1 = std::make_tuple("one"sv, "two"sv, "three"sv);
auto t2 = std::make_tuple("one"sv, "two"sv, "three"sv);
and you'll get what you expect. (In pre-c++17 compilers, use <string> and ""s instead of <string_view> and ""sv).
What is the type of "one"? This is not a string, but rather a string literal.
Your problem basically boils down to this code:
char const* a = "one";
char const* b = "one";
std::cout << "(a == b) is " << std::boolalpha << (a == b) << "\n";
std::cout << "(a != b) is " << std::boolalpha << (a != b) << "\n";
Which will most likely output the same result.
This is because a string literal will decay into a char const*. Comparing two pointer compares their location in memory. Now this is a matter of whether your compiler is folding string literals into one. If the string literals are folded, then they are gonna be equal, if they are not, they are not gonna be equal. This can vary with different optimization levels.
How can you fix your comparison then?
Preferably use std::string_view as you don't seem to need to own or change their content:
using namespace std::literals;
// ...
auto t1 = std::make_tuple("one"sv, "two"sv, "three"sv);
auto t2 = std::make_tuple("one"sv, "two"sv, "three"sv);
The std::string_view class is a thin wrapper around a pointer and a size, and define a comparison operator that check for value equality.
The problem is unrelated to C++20, but comes from how string literals are implemented. The answer is for example here:
Why do (only) some compilers use the same address for identical string literals?
In short, your program falls into the category of "undefined unspecified behavior", as it assumes that identical C-style string literals have identical addresses. This is because expressions like "a" == "a" compare addresses, not the content. Your code could be made safe and predictable if you used std::string literals, like "one"s, "one"sv etc., see https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
auto is not always your friend. I would argue the proper way to get reliably the “right” behaviour without boilerplate is to explicitly use a type that you know has value-equality. Then you can also omit the make_tuple and simply use the initialiser-list constructor:
#include <string>
#include <tuple>
#include <iostream>
typedef std::tuple<std::string, std::string, std::string> StrTriple;
int main() {
StrTriple t1{"one", "two", "three"};
StrTriple t2{"one", "two", "three"};
std::cout << "(t1 == t2) is " << std::boolalpha << (t1 == t2) << "\n";
std::cout << "(t1 != t2) is " << std::boolalpha << (t1 != t2) << "\n";
return 0;
}
No doubt some would argue that the memory management of std::string incurs unnecessary overhead. string_view may be preferrable, however chances are in a real-world application the strings will need to be dynamically allocated anyway somewhere.
Getting input from another source; which populates a string of up to 2048 characters.
What is the most efficient way of populating and comparing this string? - I want to be able to easily append to the string also.
Here are three attempts of mine:
C-style version
#include <cstdio>
#include <cstring>
int main(void) {
char foo[2048];
foo[0]='a', foo[1]='b', foo[2]='c', foo[3]='\0'; // E.g.: taken from u-input
puts(strcmp(foo, "bar")? "false": "true");
}
C++-style version 0
#include <iostream>
int main() {
std::string foo;
foo.reserve(2048);
foo += "abc"; // E.g.: taken from user-input
std::cout << std::boolalpha << (foo=="bar");
}
C++-style version 1
#include <iostream>
int main() {
std::string foo;
foo += "abc"; // E.g.: taken from user-input
std::cout << std::boolalpha << (foo=="bar");
}
What is most efficient depends on what you optimize for.
Some common criteria:
Program Speed
Program Size
Working Set Size
Code Size
Programmer Time
Safety
Undoubted King for 1 and 2, in your example probably also 3, is C style.
For 4 and 5, C++ style 1.
Point 6 is probably with C++-style.
Still, the proper mix of emphasizing these goal is called for, which imho favors C++ option 0.
I try to force my compiler to replace any std::cout occurrence in my code with something.
But when I write something like that:
#define std::cout (*some code*)
My compiler spit on my face. Is there a way to do this ?
EDIT :
Here is the code snippet:
# define std::cout (std_out << std::cout)
(std_out is a file I've previously open)
and the error on a line with a std::out occurence
the global scope has no "cout"
You define an identifier, not an arbitrary expression. std is
an identifier; your define will cause the compiler to replace
every instance of the identifier std with ::cout (*some
code*). So it's not surprising that the compiler doesn't like
it: std::cout << toto becomes ::cout (*some code*)::cout <<
toto and std::vector becomes ::cout (*some code*)::vector.
If you'd explain what you're actually trying to achieve, we could probably help you better.
I try to force my compiler to replace any std::cout occurence in my code with something
That's a bad idea. If you are looking for configurable behavior on your output stream, replace all occurrences of std::cout in your code with out, and declare out as std::ostream& out (= whatever stream type you may need).
My compiler spit on my face. Is there a way to do this ?
Not as such. No. You could write:
#define OUTPUT std::cout
OUTPUT << "a = " << a << std::endl;
but you needing a #define to disable (or redirect) your output stream is a sign of bad design (i.e. your define is not the problem you should be trying to solve).
You can make your own version of cout, that actually calls cout, you can place any custom code there:
std::ostream& my_cout() {
/// ...
return std::cout << "a custom message";
}
int main() {
my_cout() << " hi" << std::endl;
}
I just find out that this little piece of C++ code doesn't give me the same result with clang++ and with g++:
#include <iostream>
#include <string>
using namespace std;
const string& createString(char c) {
static string s;
s="";
for(int i=0; i<10; ++i) {
s+=c;
}
return s;
}
int main() {
cout << createString('a') << ' ' << createString('z') << endl;
return 0;
}
With clang++ it writes:
aaaaaaaaaa zzzzzzzzzz
like I want it to be, but with g++ it writes:
aaaaaaaaaa aaaaaaaaaa
Why is it so? Is the g++ implementation standard compliant?
And what should I do if I want a function to return a temporary "big" type by reference like here to avoid useless copy?
Yes, both implementations are compliant. The order of evaluation of function arguments is not specified.
Therefore, createString('a') and createString('z') can be evaluated in any order. Furthermore, createString('z') can be evaluated before or after the result of createString('a') is written out.
Since the function is stateful, and returns the state by reference, both outputs are permissible, as is zzzzzzzzzz zzzzzzzzzz.
Finally, it is worth noting that having static state would be a major headache in a multithreaded environment.
And what should I do if I want a function to return a temporary "big"
type by reference like here to avoid useless copy ?
It won't be. RVO and NRVO can trivially take care of this. In addition, move semantics. In short, there's nothing problematic about returning a std::string by value at all.
And what should I do if I want a function to return a temporary "big" type by reference like here to avoid useless copy ?
Call it only once per expression. For example, this will work fine:
std::cout << createString('a') << ' ';
std::cout << createString('z') << std::endl;
Is there some way to do something like this in c++, it seems sizeof cant be used there for some reason?
#if sizeof(wchar_t) != 2
#error "wchar_t is expected to be a 16 bit type."
#endif
No, this can't be done because all macro expansion (#... things) is done in the pre-processor step which does not know anything about the types of the C++ code and even does not need to know anything about the language!
It just expands/checks the #... things and nothing else!
There are some other common errors, for example:
enum XY
{
MY_CONST = 7,
};
#if MY_CONST == 7
// This code will NEVER be compiled because the pre-processor does not know anything about your enum!
#endif //
You can only access and use things in #if that are defined via command line options to the compiler or via #define.
The preprocessor works without knowing anything about the types, even the builtin one.
BTW, you can still do the check using a static_assert like feature (boost has one for instance, C++0X will have one).
Edit: C99 and C++0X have also WCHAR_MIN and WCHAR_MAX macros in <stdint.h>
I think things like BOOST_STATIC_ASSERT could help.
Wouldn't you get basically what you want (compile error w/o the fancy message) by using a C_ASSERT?
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
sizeof() is a runtime compile-time function. You cannot call that in a preprocessor directive. I don't think you can check the size of wchar_t during preprocessing. (see Edit 2)
Edit: As pointed out in comments, sizeof() is mostly calculated at compile time. In C99, it can be used at runtime for arrays.
Edit 2: You can do asserts at build time using the techniques described in this thread.
char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1];
I've developed some macros that will effectively allow you to use sizeof within a macro condition. They're in a header file that I've uploaded here (MIT license).
It will permit for code like this:
#include <iostream>
#include "SIZEOF_definitions.h"
//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int)
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int)
#if SIZEOF(unsigned, int) == 4
int func() { return SIZEOF_BIT(unsigned, int); }
#elif SIZEOF(unsigned, int) == 8
int func() { return 2 * SIZEOF_BIT(unsigned, int); }
#endif
int main(int argc, char** argv) {
std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n'
<< SIZEOF(unsigned, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, int) << '\n'
<< SIZEOF(int) << " chars, #bits = " << SIZEOF_BIT(int) << '\n';
std::cout << func() << std::endl;
return 0;
}
Note the commas within SIZEOF(unsigned, long, int).