web-dev-qa-db-fra.com

Quel est le spécificateur de format printf pour bool?

Depuis ANSI C99, il y a _Bool ou bool via stdbool.h. Mais existe-t-il également un spécificateur de format printf pour bool?

Je veux dire quelque chose comme dans ce pseudo-code:

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

qui imprimerait:

true
386
maxschlepzig

Il n'y a pas. Mais comme tout type d'intégrale inférieur à int est promu à int lorsqu'il est transmis à des arguments variés printf(), vous pouvez utiliser %d:

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

Mais pourquoi pas

printf(x ? "true" : "false");

ou mieux

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

ou même mieux

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

au lieu?

605
user529758

Il n'y a pas de spécificateur de format pour bool. Vous pouvez l’imprimer en utilisant certains des spécificateurs existants pour l’impression de types intégraux ou faire quelque chose de plus original:

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

La norme ANSI C99/C11 n'inclut pas de spécificateur de conversion printf supplémentaire pour bool.

Mais la bibliothèque GNU C fournit une API permettant d’ajouter des spécificateurs personnalisés .

Un exemple:

#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;
}

Comme il s’agit d’une extension de la glibc, le GCC met en garde sur ce spécificateur personnalisé:

 $ gcc -Wall -g main.c -o main 
 main.c: Dans la fonction 'main': 
 main.c: 34: 3: avertissement: type de conversion inconnu caractère 'B' au format [-Wformat =] 
 r = printf ("Le résultat est:% B\n", b); 
 ^ 
 main.c: 34 : 3: attention: trop d'arguments pour le format [-Wformat-extra-args] 

Sortie:

Le résultat est: faux 
 (écrit en 21 caractères) 
 $ ./main 1 
 Le résultat est: vrai 
 .____.] (écrit 20 caractères) 
30
maxschlepzig

Dans la tradition de itoa():

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

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

Vous ne pouvez pas, mais vous pouvez imprimer 0 ou 1

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

source

4
Stephan

Je préfère une réponse de meilleure façon d’imprimer le résultat d’une erreur comme "faux" ou "vrai" dans c? , comme

printf("%s\n", "false\0true"+6*x);
  • x == 0, "faux\0 vrai" + 0 "cela signifie" faux ";
  • x == 1, "faux\0 vrai" + 6 "cela signifie" vrai ";
2
xjzhou

Pour simplement imprimer 1 ou 0 en fonction de la valeur booléenne que je viens d'utiliser:

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

Particulièrement utile avec les drapeaux:

#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));
2
Tarion

Si vous aimez mieux le C++ que le C, vous pouvez essayer ceci:

#include <ios>
#include <iostream>

bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
1
Arsen Y.M.