617 votes

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

Depuis la norme ANSI C99, il existe _Bool o bool via stdbool.h . Mais existe-t-il aussi un printf spécificateur de format pour bool ?

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

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

qui s'imprimerait :

true

1 votes

Vous pouvez lire ceci pour plus d'informations cplusplus.com/reference/cstdio/printf Mais vous pouvez toujours le faire !

0 votes

3 votes

@billinkc, ma question n'est pas vraiment à propos de quoi le meilleur moyen est d'imprimer des valeurs de bools - il s'agit d'un spécificateur printf concret. Qui ne semble pas exister. Un autre angle pour une bonne réponse serait : peut-être qu'il y a un moyen d'ajouter un spécificateur de format personnalisé à printf qui fait la conversion bool ...

952voto

Il n'y a pas de spécificateur de format pour bool types. Cependant, puisque tout type intégral plus court que int est promu à int lorsqu'il est transmis à printf() vous pouvez utiliser les arguments variadiques de l'option %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, encore mieux :

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

à la place ?

26 votes

J'ajouterais +1 si vous vous débarrassez de l'expression littérale qui n'est pas une simple chaîne de caractères comme chaîne de format. Ce type d'utilisation se transforme facilement en une utilisation non sûre. printf("%s", x ? "true" : "false"); réglerait le problème.

2 votes

Pour la partie "pourquoi pas" de cette réponse -- un spécificateur de format pour bool permettrait à la chaîne de format d'être utilisée comme prévu : pour construire une chaîne avec un mélange de littéraux et de valeurs.

21 votes

Juste comme une note, j'aurais tendance à contester que printf("%s", x ? "true" : "false"); es meilleur que printf(x ? "true" : "false"); - vous êtes dans total contrôle de la chaîne de format ici, donc il y a pas de le risque que cela donne quelque chose comme "%d" ce qui poserait des problèmes. Le site fputs d'autre part, est une meilleure option.

59voto

Ivaylo Strandjev Points 38924

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 des types intégraux ou faire quelque chose de plus fantaisiste :

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

0 votes

@H2CO3 de toute façon j'ai proposé une solution pour imprimer "vrai" et "faux" comme le demande le PO. J'ai également légèrement modifié ma formulation sur la partie que vous mentionnez.

5 votes

@IvayloStrandjev : Oui, il y a es a bool en C, mais pas dans l'édition C89 -- il fait partie de la spécification du langage C99. Il y a un nouveau mot-clé _Bool et si vous incluez <stdbool.h> alors bool est un synonyme de _Bool .

39voto

maxschlepzig Points 3578

ANSI C99/C11 n'incluent pas un spécificateur de conversion printf supplémentaire pour bool .

Mais le La bibliothèque GNU C fournit une API pour 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, la GCC émet un avertissement à propos de ce spécificateur personnalisé :

$ 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\]

Sortie :

$ ./main
The result is: false
(written 21 characters)
$ ./main 1
The result is: true
(written 20 characters)

13voto

jxh Points 32720

Dans la tradition de itoa() :

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

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

5 votes

btoa est "chaîne binaire vers chaîne base 64" en JavaScript non standard (Gecko et WebKit), vous pouvez donc utiliser un nom différent.

39 votes

@panzi : Je ne suis pas sûr que cela vaille la peine pour un programmeur C de s'inquiéter des identifiants JavaScript non standard.

5 votes

@KeithThompson Je pense que j'ai confondu les questions et j'ai cru que cela concernait JavaScript, ce qui n'a aucun sens de toute façon. C'était probablement tard dans la nuit.

5voto

Stephan Points 2942

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

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

source

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X