Depuis ANSI C99 il y a _Bool
ou bool
via stdbool.h
. Mais existe-t-il également 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 imprimerait:
true
Depuis ANSI C99 il y a _Bool
ou bool
via stdbool.h
. Mais existe-t-il également 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 imprimerait:
true
Réponses:
Il n'y a pas de spécificateur de format pour les bool
types. Cependant, comme tout type intégral plus court que celui int
promu int
lorsqu'il est transmis aux printf()
arguments variadiques de, 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 encore mieux:
fputs(x ? "true" : "false", stdout);
au lieu?
printf("%s", x ? "true" : "false");
résoudrait le problème.
printf("%s", x ? "true" : "false");
c'est mieux que printf(x ? "true" : "false");
- vous avez le contrôle total de la chaîne de format ici, donc il n'y a aucun danger qu'il obtienne quelque chose comme ça "%d"
qui causerait des problèmes. Le fputs
, d'autre part, est une meilleure option.
fputs
"encore mieux"? Je cherche toujours des moyens d'améliorer mon C. Dans quelles circonstances dois-je utiliser à la fputs
place printf
?
Il n'y a pas de spécificateur de format pour bool. Vous pouvez l'imprimer en utilisant certains des spécificateurs existants pour imprimer des types intégraux ou faire quelque chose de plus sophistiqué:
printf("%s", x?"true":"false");
bool
type en C, mais pas dans l'édition C89 - cela fait partie des spécifications du langage C99. Il y a un nouveau mot _Bool
- clé , et si vous l'incluez <stdbool.h>
, alors bool
c'est un synonyme pour _Bool
.
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 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 glibc, le GCC met en garde contre ce spécificateur personnalisé:
$ gcc -Wall -g main.c -o main main.c: Dans la fonction 'main': main.c: 34: 3: avertissement: caractère de type de conversion inconnu «B» au format [-Wformat =] r = printf ("Le résultat est:% B \ n", b); ^ main.c: 34: 3: avertissement: trop d'arguments pour le format [-Wformat-extra-args]
Production:
$ ./main Le résultat est: faux (écrit 21 caractères) $ ./principal 1 Le résultat est: vrai (écrit 20 caractères)
Dans la tradition de itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
est "chaîne binaire à chaîne de base 64" en JavaScript non standard (Gecko et WebKit), vous pouvez donc utiliser un nom différent.
"true\0false"[(!x)*5]
:-)
!!x*5
.
Si vous aimez mieux C ++ que C, vous pouvez essayer ceci:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Pour imprimer simplement 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));
!!
pourrait être optimisé
Je préfère une réponse de Best way pour imprimer le résultat d'un booléen comme «faux» ou «vrai» en c? , juste comme
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
qui s'est réellement passé. Si vous travaillez dans un projet avec d'autres personnes, ou simplement dans un projet avec une base de code que vous souhaitez comprendre x ans plus tard, des constructions comme celle-ci doivent être évitées.
printf("%s\n","false\0true"+6*(x?1:0));
qui n'est que ... 5% moins lisible.
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Identique à static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; il suffit de l'envelopper dans une fonction nommée de manière descriptive et ne vous inquiétez pas de sa lisibilité.