ChatGPT解决这个技术问题 Extra ChatGPT

What is the printf format specifier for bool?

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
You can read this for further information cplusplus.com/reference/cstdio/printf You can always make it though!
@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 ...
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.
@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.

A
Adrian Mole

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(x ? "true" : "false");

or, better:

printf("%s", x ? "true" : "false");

or, even better:

fputs(x ? "true" : "false", stdout);

instead?


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.
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.
@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). 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.
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, 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.
Y
Yun

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");

@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.
@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 <stdbool.h>, then bool is a synonym for _Bool.
m
maxschlepzig

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)

j
jxh

In the tradition of itoa():

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

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

btoa is "binary string to base 64 string" in non-standard JavaScript (Gecko and WebKit), so you might want to use a different name.
@panzi: I'm not sure it's worth the effort for a C programmer to worry about non-standard JavaScript identifiers.
@KeithThompson I think I confused the questions and somehow thought this was about JavaScript, which makes no sense anyway. It was probably late at night.
Or, for the more devious amongst us: "true\0false"[(!x)*5] :-)
@MooingDuck: maybe !!x*5.
C
Community

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

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

source


A
Arsen Y.M.

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

#include <ios>
#include <iostream>

bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;

This answer is off-topic and should be deleted, since it is about another language than the one in the question.
@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++, this is the first page that comes up (although arguably this page 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.
@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 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.
@JeffG You can bring it up on meta.stackoverflow.com, this is not the place to have this discussion.
T
Tarion

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));

Beware that the !! might get optimized away
@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.
C
Community

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";


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.
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).
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 You could of course change it to printf("%s\n","false\0true"+6*(x?1:0)); which is only... 5% less readable.
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.