@billinkc, ma question n'est pas vraiment de savoir quelle est la meilleure façon d'imprimer des valeurs booléennes - il s'agit d'un spécificateur printf concret. Ce qui ne semble pas exister. Un autre angle pour une bonne réponse serait: peut-être qu'il existe un moyen d'ajouter un spécificateur de format personnalisé à printf qui effectue la conversion
booléenne
Très bien, même si je ne semble pas avoir la possibilité de dévoiler la VtC, je vais donc devoir attendre que mon vote expire.
billinkc
@maxschlepzig: la seule façon de résoudre le problème est de vérifier la documentation. Si vous utilisez GNU / Linux (par exemple, puisque vous ne nous avez pas parlé de votre système), vous pouvez lire un manuel printf à jour sur [Linux man pages] (man7.org). Si vous voulez imprimer des chaînes "true" / "false", vous pouvez les construire manuellement, c'est assez simple.
Bulat M.
Réponses:
711
Il n'y a pas de spécificateur de format pour les booltypes. Cependant, comme tout type intégral plus court que celui intpromu intlorsqu'il est transmis aux printf()arguments variadiques de, vous pouvez utiliser %d:
Je voudrais +1 si vous vous débarrassez de l'expression littérale non à chaîne unique en tant que chaîne de format. Ce type d'utilisation se transforme facilement en utilisation dangereuse. printf("%s", x ? "true" : "false");résoudrait le problème.
R .. GitHub STOP HELPING ICE
2
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.
noamtm
13
Juste comme une note, j'aurais tendance à contester que 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.
paxdiablo
15
Pourquoi est-ce fputs"encore mieux"? Je cherche toujours des moyens d'améliorer mon C. Dans quelles circonstances dois-je utiliser à la fputsplace printf?
Arc676
10
@ Arc676, pour une chaîne sans formatage, fputs est plus rapide et plus simple que printf (qui doit analyser la chaîne à la recherche de caractères de formatage). L'utilisation de fputs (stdout) plutôt que simplement de metts () (qui par défaut est stdout) élimine le retour à la ligne qui ajoute () à la sortie.
Tchad
45
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é:
@ H2CO3 de toute façon, j'ai proposé une solution affichant "vrai" et "faux" comme des demandes OP. J'ai également légèrement modifié ma formulation dans la partie que vous mentionnez.
Ivaylo Strandjev
5
@IvayloStrandjev: Oui, il y a un booltype 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 boolc'est un synonyme pour _Bool.
Adam Rosenfield
30
ANSI C99 / C11 n'inclut pas de spécificateur de conversion printf supplémentaire pour bool.
#include<stdio.h>#include<printf.h>#include<stdbool.h>staticint bool_arginfo(conststruct printf_info *info,size_t n,int*argtypes,int*size){if(n){
argtypes[0]= PA_INT;*size =sizeof(bool);}return1;}staticint bool_printf(FILE *stream,conststruct printf_info *info,constvoid*const*args){bool b =*(constbool*)(args[0]);int r = fputs(b ?"true":"false", stream);return r == EOF ?-1:(b ?4:5);}staticint 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)return1;bool b = argc >1;
r = printf("The result is: %B\n", b);
printf("(written %d characters)\n", r);return0;}
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)
btoaest "chaîne binaire à chaîne de base 64" en JavaScript non standard (Gecko et WebKit), vous pouvez donc utiliser un nom différent.
panzi
26
@panzi: Je ne suis pas sûr que cela vaille la peine qu'un programmeur C s'inquiète des identifiants JavaScript non standard.
Keith Thompson
5
@KeithThompson Je pense que j'ai confondu les questions et que je pensais que c'était à propos de JavaScript, ce qui n'a aucun sens de toute façon. Il était probablement tard dans la nuit.
panzi
9
Ou, pour les plus sournois d'entre nous: "true\0false"[(!x)*5]:-)
paxdiablo
1
@MooingDuck: peut-être !!x*5.
jxh
4
Vous ne pouvez pas, mais vous pouvez imprimer 0 ou 1
Cette réponse est hors sujet et doit être supprimée, car il s'agit d'une autre langue que celle de la question.
Lundin
2
@Lundin Je ne suis pas d'accord pour que cela soit supprimé. L'objectif de SO n'est pas seulement d'aider une seule personne, mais d'aider toutes les personnes ayant la même question. Lorsque je recherche le sprintf print boolean comme true false c ++ , c'est la première page qui apparaît (bien que sans doute cette page ait pu être le meilleur résultat si cette réponse n'existait pas). Étant donné que C ++ est presque un surensemble de C, je ne pense pas que de telles réponses devraient être si facilement rejetées. +1 de moi.
Jeff G
1
@JeffG Oui, ces réponses doivent être supprimées, nous avons des politiques très claires. Lisez les wikis des balises C et C ++. Cette question n'est pas utile aux programmeurs C, en particulier parce que les systèmes booléens C et C ++ sont entièrement différents et la question est étiquetée C. Que Google ne soit pas en mesure de comprendre les deux ++ derrière dans votre recherche n'est pas le problème de SO.
Lundin
2
@Lundin Mon commentaire n'était pas destiné à être interprété comme un commentaire sur les politiques de SO. C'était vraiment un commentaire pour savoir si cette réponse ajoute de manière constructive à la question. Cette réponse est immédiatement identifiable en C ++ uniquement. Personne ne venant ici pour une réponse en C uniquement serait trompé en pensant que cela fonctionnerait en C et perdrait du temps à essayer. Cependant, c'est une excellente réponse pour C ++. Si les réponses sont utiles, même si elles n'aident pas le PO, ne devraient-elles pas être conservées? Je pense que les réponses constructives qui ont clairement identifié des mises en garde ne devraient jamais être supprimées, quelle que soit la politique.
C'est totalement incompréhensible. Il m'a fallu un bon moment avant de comprendre ce "false\0true"+6*xqui 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.
HelloGoodbye
3
Bien que je vois que cela pourrait être plus optimisé car il est sans branche. Si la vitesse est votre préoccupation, cela pourrait être une option, assurez-vous d'expliquer bien les mécanismes derrière l'astuce dans un commentaire. Une fonction ou une macro en ligne avec un nom auto-documenté serait également utile (mais probablement pas suffisante dans ce cas).
HelloGoodbye
3
En plus des inquiétudes concernant la lisibilité, gardez à l'esprit que cela explosera si quelqu'un passe une valeur autre que 0 ou 1.
plugwash
2
@plugwash Vous pouvez bien sûr le changer, ce printf("%s\n","false\0true"+6*(x?1:0));qui n'est que ... 5% moins lisible.
hoosierEE
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é.
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 celuiint
promuint
lorsqu'il est transmis auxprintf()
arguments variadiques de, vous pouvez utiliser%d
:Mais pourquoi pas:
ou mieux:
ou encore mieux:
au lieu?
la source
printf("%s", x ? "true" : "false");
résoudrait le problème.printf("%s", x ? "true" : "false");
c'est mieux queprintf(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. Lefputs
, 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 à lafputs
placeprintf
?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é:
la source
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>
, alorsbool
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:
Comme il s'agit d'une extension glibc, le GCC met en garde contre ce spécificateur personnalisé:
Production:
la source
Dans la tradition de
itoa()
:la source
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
.Vous ne pouvez pas, mais vous pouvez imprimer 0 ou 1
la source
la source
Si vous aimez mieux C ++ que C, vous pouvez essayer ceci:
la source
Pour imprimer simplement 1 ou 0 en fonction de la valeur booléenne que je viens d'utiliser:
Particulièrement utile avec les drapeaux:
la source
!!
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
la source
"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é.