675

Since ANSI C99 there is _Bool or bool via stdbool.h. But is there also a printf format specifier for bool?

I mean something like in that pseudo code:

bool x = true;
printf("%B\n", x);

which would print:

true
General Grievance
  • 4,555
  • 31
  • 31
  • 45
maxschlepzig
  • 35,645
  • 14
  • 145
  • 182
  • 2
    You can read this for further information http://www.cplusplus.com/reference/cstdio/printf/ You can always make it though! – Varvarigos Emmanouil Jun 25 '13 at 20:52
  • 1
    possible duplicate of [Best way to print the result of a bool as 'false' or 'true' in c?](http://stackoverflow.com/questions/7617479/best-way-to-print-the-result-of-a-bool-as-false-or-true-in-c) – billinkc Jun 25 '13 at 21:19
  • 5
    @billinkc, my question is not really about what *the best way* is to print bool values - it is about a concrete printf specifier. Which does not seem to exist. Another angle to a nice answer would be: perhaps there is a way to add a custom format specifier to printf that does the bool conversion ... – maxschlepzig Jun 25 '13 at 21:53
  • 1
    Fair enough, although I don't seem to have the ability to uncast the VtC so I'll just have to wait for my vote to expire. – billinkc Jun 25 '13 at 21:55
  • 1
    @maxschlepzig: the only way to solve the problem is to check documentation. If you use GNU/Linux(as example, since you did not tell us about your system), you can read an up-to-date printf manual on [Linux man pages](man7.org). If you want get "true"/"false" strings printed, you can construct them manually, it is pretty easy. – Bulat M. Oct 05 '16 at 02:57

8 Answers8

1039

There is no format specifier for bool types. However, since any integral type shorter than int is promoted to int when passed down to printf()'s variadic arguments, you can use %d:

bool x = true;
printf("%d\n", x); // prints 1

But why not:

printf("Your boolean variable is: %s", x ? "true" : "false");

instead?

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 31
    I would +1 this if you get rid of the non-single-string-literal expression as the format string. This kind of usage easily turns into unsafe usage. `printf("%s", x ? "true" : "false");` would fix the issue. – R.. GitHub STOP HELPING ICE Jun 25 '13 at 21:02
  • 2
    For the "why not" part of this answer -- a format specifier for bool would allow the format string to be used as designed: for constructing a string with a mixture of literals and values. – noamtm Feb 09 '14 at 09:21
  • 25
    Just as a note, I'd tend toward disputing that `printf("%s", x ? "true" : "false");` is _better_ that `printf(x ? "true" : "false");` - you are in _total_ control of the format string here so there is _no_ danger that it'll get something like `"%d"` which would cause problems. The `fputs`, on the other hand, _is_ a better option. – paxdiablo Oct 15 '14 at 02:40
  • In my case,`%d`give -1 or 0. And`%ld`give MAX_INT. – user2284570 Apr 29 '15 at 01:05
  • Why is `fputs(x ? "true" : "false", stdout);` better than `printf("%s", x ? "true" : "false");` and the latter better than `printf(x ? "true" : "false");`? – HelloGoodbye Jun 30 '15 at 16:12
  • 6
    @HelloGoodbye, passing a single `char *` to `printf()` is considered bad practice because it's really supposed to be a format string, and an unescaped percent sign might cause your program to blow up ([see here for more](http://stackoverflow.com/questions/31290850/why-is-printf-with-a-single-argument-without-conversion-specifiers-deprecated)). Thus, `printf("%s", ...)` is safer. If you're not doing any actual *formatting* to begin with, the `printf` family of functions is overkill and `puts()` (or `fputs()` if you need to print to `stderr`) is preferable because it's more efficient/concise. – sevko Jul 14 '15 at 03:06
  • 2
    @r: How could this be unsafe? It does not contain any format specifier in the format string - no matter what the ternary operator returns, the format string is always a perfectly save pure string literal. – Kaiserludi Jul 31 '15 at 12:11
  • 1
    I did +1 this, but I'm not sure about your comment regarding "prints 1." I have not read the standard, but I seem to recall from other texts reading that `false` is zero, and `true` is "non-zero." Based on implementation, it may print 9, 24, or even a negative value, like -1. If I'm correct, you may want to update your comment to say "prints non-zero" so as to further discourage that unfavorable method. – Luv2code Aug 06 '15 at 16:25
  • 23
    Why is `fputs` "even better"? I'm always looking for ways to improve my C. Under what circumstances should I use `fputs` instead of `printf`? – Arc676 Aug 15 '15 at 10:50
  • 1
    Downvoted for the "why not". That's like saying "why not just format everything yourself?". The obvious answer is "because I'm using a formatting print, I expect it to format all my types sensibly". – GreenAsJade Jan 04 '17 at 23:14
  • 19
    @Arc676, for a string without formatting, fputs is faster and simpler than printf (which has to parse the string looking for formatting chars). Using fputs(stdout) rather than just puts() (which defaults to stdout) eliminates the newline that puts() appends to the output. – Chad Sep 25 '17 at 20:20
  • 2
    A good compiler should replace `printf()` by `fputs(stdout)` whenever possible, so efficiency is the same. – alx - recommends codidact Mar 02 '19 at 12:22
72

There is no format specifier for bool. You can print it using some of the existing specifiers for printing integral types or do something more fancy:

printf("%s", x?"true":"false");
Yun
  • 3,056
  • 6
  • 9
  • 28
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • 1
    @H2CO3 anyways I have suggested a solution printing "true" and "false" as OP requests. I have also slightly changed my wording on the part you mention. – Ivaylo Strandjev Jun 25 '13 at 20:54
  • 6
    @IvayloStrandjev: Yes, there *is* a `bool` type in C, just not in the C89 edition -- it's part of the C99 language spec. There's a new keyword `_Bool`, and if you include ``, then `bool` is a synonym for `_Bool`. – Adam Rosenfield Jun 25 '13 at 20:58
40

ANSI C99/C11 don't include an extra printf conversion specifier for bool.

But the GNU C library provides an API for adding custom specifiers.

An example:

#include <stdio.h>
#include <printf.h>
#include <stdbool.h>

static int bool_arginfo(const struct printf_info *info, size_t n,
    int *argtypes, int *size)
{
  if (n) {
    argtypes[0] = PA_INT;
    *size = sizeof(bool);
  }
  return 1;
}
static int bool_printf(FILE *stream, const struct printf_info *info,
    const void *const *args)
{
  bool b =  *(const bool*)(args[0]);
  int r = fputs(b ? "true" : "false", stream);
  return r == EOF ? -1 : (b ? 4 : 5);
}
static int setup_bool_specifier()
{
  int r = register_printf_specifier('B', bool_printf, bool_arginfo);
  return r;
}
int main(int argc, char **argv)
{
  int r = setup_bool_specifier();
  if (r) return 1;
  bool b = argc > 1;
  r = printf("The result is: %B\n", b);
  printf("(written %d characters)\n", r);
  return 0;
}

Since it is a glibc extensions the GCC warns about that custom specifier:

$ gcc -Wall -g    main.c   -o main
main.c: In function ‘main’:
main.c:34:3: warning: unknown conversion type character ‘B’ in format [-Wformat=]
   r = printf("The result is: %B\n", b);
   ^
main.c:34:3: warning: too many arguments for format [-Wformat-extra-args]

Output:

$ ./main
The result is: false
(written 21 characters)
$ ./main 1
The result is: true
(written 20 characters)
maxschlepzig
  • 35,645
  • 14
  • 145
  • 182
14

In the tradition of itoa():

#define btoa(x) ((x)?"true":"false")

bool x = true;
printf("%s\n", btoa(x));
jxh
  • 69,070
  • 8
  • 110
  • 193
5

You can't, but you can print 0 or 1

_Bool b = 1;
printf("%d\n", b);

source

Community
  • 1
  • 1
Stephan
  • 16,509
  • 7
  • 35
  • 61
3

To just print 1 or 0 based on the boolean value I just used:

printf("%d\n", !!(42));

Especially useful with Flags:

#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));
Tarion
  • 16,283
  • 13
  • 71
  • 107
  • 1
    Beware that the `!!` might get optimized away – interestedparty333 Sep 11 '19 at 03:07
  • 1
    @interestedparty333: If MY_FLAG were equal to 1, then `!!(flags & MY_FLAG)` could get replaced with `(flags & MY_FLAG)`, but a non-broken compiler would not be able to optimize away `!!` unless it could prove that the operand couldn't have any value other than 0 or 1. – supercat Jun 10 '21 at 20:42
2

If you like C++ better than C, you can try this:

#include <ios>
#include <iostream>

bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Arsen Y.M.
  • 673
  • 1
  • 7
  • 18
  • 9
    This answer is off-topic and should be deleted, since it is about another language than the one in the question. – Lundin Sep 04 '18 at 08:55
  • 6
    @Lundin I disagree that this should be deleted. The goal of SO isn't just to help one person, but to help all people with the same question. When I search for [sprintf print boolean as true false c++](https://www.google.com/search?q=sprintf+print+boolean+as+true+false+c%2B%2B), this is the first page that comes up (although arguably [this page](https://stackoverflow.com/questions/29383/converting-bool-to-text-in-c) may have been the top result if this answer didn't exist). Since C++ is nearly a superset of C, I don't think such answers should be so easily discarded. +1 from me. – Jeff G Mar 17 '19 at 19:15
  • 2
    @JeffG Yes such answers should be deleted, we have very clear policies. Read the C and C++ tag wikis. This question isn't helpful to C programmers **particularly because the C and C++ boolean systems are entirely different** and the question is tagged C. That Google isn't able to understand the two trailing ++ in your search isn't SO's problem. – Lundin Mar 18 '19 at 07:24
  • 3
    @Lundin My comment wasn't intended to be interpreted as a comment on SO's policies. It was really a comment about whether this answer adds constructively to the question. This answer is immediately identifiable as C++-only. Nobody coming here for a C-only answer would be tricked into thinking this would work in C and waste time trying it. However, this is a great answer for C++. If answers are useful, even if they don't help the OP, then shouldn't they be kept? I think constructive answers that have clearly identified caveats should never be deleted, regardless of policy. – Jeff G Mar 18 '19 at 23:04
  • 3
    @JeffG You can bring it up on https://meta.stackoverflow.com, this is not the place to have this discussion. – Lundin Mar 19 '19 at 07:35
-2

I prefer an answer from Best way to print the result of a bool as 'false' or 'true' in c?, just like

printf("%s\n", "false\0true"+6*x);
  • x == 0, "false\0true"+ 0" it means "false";
  • x == 1, "false\0true"+ 6" it means "true";
Community
  • 1
  • 1
xjzhou
  • 563
  • 5
  • 4
  • 29
    This is totally incomprehensible. It took me a good while before I figured out what `"false\0true"+6*x` really did. If you work in a project with other people, or just in a project whit a codebase you want to understand _x_ years later, constructions like this is to be avoided. – HelloGoodbye Jun 30 '15 at 16:23
  • 3
    Although I see that this might be more optimized since it is branch-less. If speed is your concern, this might be an option, just make sure to explain the mechanics behind the trick well in a comment. An inline function or macro with a self-documenting name would also be helpful (but probably not sufficient in this case). – HelloGoodbye Jun 30 '15 at 16:46
  • 3
    As well as the concerns about readability bear in mind that this will blow up if someone passes in a value other than 0 or 1. – plugwash Oct 13 '15 at 14:05
  • 2
    @plugwash You could of course change it to `printf("%s\n","false\0true"+6*(x?1:0));` which is only... 5% less readable. – Alex Shroyer Nov 18 '15 at 18:36
  • `static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }` Same as with `static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }`; just wrap it in a descriptively named function and don't worry about it's readability. – yyny Feb 08 '18 at 21:58
  • 1
    Premature optimization. All modern compilers on x86-64 or ARM64 will compile `puts( tf ? "true" : "false" );` as a conditional-move instruction, not a branch. On architectures where it would be more efficient, they can generally replace that with something like `(char*)((uintptr_t)option1^ (((uintptr_t)x-1U)&((uintptr_t)option1^(uintptr_t)option2)))` on targets where that's more efficient. That code is a maintenance nightmare. – Davislor May 06 '19 at 04:14
  • 1
    Another problem with this solution is that if it is used in foreign languages the number 6 would have to be changed. For example, if x is true "ложь\0истина" + 6*x would print "ь" the last letter in the Russian word for false, because in UTF-8 encoding that word occupies 8 bytes rather than 5. The number 6 would have to be changed to 9. – Thomas Hedden Feb 07 '22 at 17:19
  • 1
    @AlexShroyer what about `"false\0true"+6 *!!a` ... ;) FWIW, a [godbolt link](https://gcc.godbolt.org/z/bn9rEWcPP) that illustrates @Davislor's point. – maxschlepzig Jul 10 '22 at 15:37