@ Billinkc, minha pergunta não é realmente sobre qual é a melhor maneira de imprimir valores bool - é sobre um especificador concreto printf. O que parece não existir. Outro ângulo para uma resposta boa seria: talvez haja uma maneira de adicionar um especificador de formato personalizado para printf que faz a conversão bool ...
maxschlepzig
É justo, embora eu não pareça ter a capacidade de cancelar a transmissão do VtC, então terei que esperar que meu voto expire.
billinkc
@maxschlepzig: a única maneira de resolver o problema é verificar a documentação. Se você usa o GNU / Linux (como exemplo, como você não nos falou sobre o seu sistema), pode ler um manual de impressão atualizado em [páginas de manual do Linux] (man7.org). Se você deseja que as strings "true" / "false" sejam impressas, é possível construí-las manualmente, é muito fácil.
quer
Respostas:
711
Não há especificador de formato para booltipos. No entanto, como qualquer tipo de integrante menor que o intpromovido intquando transmitido aos printf()argumentos variados, você pode usar %d:
Eu marcaria isso com +1 se você se livrar da expressão literal de cadeia não única como a cadeia de formato. Esse tipo de uso se transforma facilmente em uso inseguro. printf("%s", x ? "true" : "false");resolveria o problema.
R .. GitHub PARE DE AJUDAR O GELO
2
Para a parte "por que não" desta resposta - um especificador de formato para bool permitiria que a string de formato fosse usada como projetada: para construir uma string com uma mistura de literais e valores.
noamtm
13
Apenas como uma observação, eu tenderia a disputar que printf("%s", x ? "true" : "false");é melhor do que isso printf(x ? "true" : "false");- você está no controle total da cadeia de caracteres de formato aqui, para que não haja perigo de obter algo como o "%d"que causaria problemas. O fputs, por outro lado, é uma opção melhor.
paxdiablo
15
Por que é fputs"ainda melhor"? Estou sempre procurando maneiras de melhorar meu C. Em que circunstâncias devo usar em fputsvez de printf?
precisa saber é o seguinte
10
@ Arc676, para uma sequência sem formatação, a saída é mais rápida e mais simples que o printf (que precisa analisar a sequência procurando caracteres de formatação). O uso de fputs (stdout) em vez de apenas puts () (cujo padrão é stdout) elimina a nova linha que coloca () anexa à saída.
Chad
45
Não há especificador de formato para bool. Você pode imprimi-lo usando alguns dos especificadores existentes para imprimir tipos integrais ou fazer algo mais sofisticado:
@ H2CO3 de qualquer maneira, sugeri uma solução imprimindo "true" e "false" conforme solicitações de OP. Também mudei levemente minha redação na parte que você mencionou.
Ivaylo Strandjev
5
@IvayloStrandjev: Sim, há é um booltipo em C, não apenas na edição C89 - é parte da especificação linguagem C99. Há uma nova palavra-chave _Boole, se você incluir <stdbool.h>, boolé sinônimo de _Bool.
Adam Rosenfield
30
O ANSI C99 / C11 não inclui um especificador de conversão extra para 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;}
Por se tratar de extensões glibc, o GCC alerta sobre esse especificador personalizado:
$ gcc -Wall -g main.c -o principal
main.c: Na função 'main':
main.c: 34: 3: aviso: caractere de tipo de conversão desconhecido 'B' no formato [-Wformat =]
r = printf ("O resultado é:% B \ n", b);
^
main.c: 34: 3: aviso: muitos argumentos para o formato [-Wformat-extra-args]
Resultado:
$ ./main
O resultado é: false
(escritos 21 caracteres)
$ ./main 1
O resultado é: true
(escritos 20 caracteres)
btoaé "string binária para a base da string 64" em JavaScript não padrão (Gecko e WebKit), portanto, convém usar um nome diferente.
Panzi # 29/13
26
@panzi: Não sei se vale a pena o esforço de um programador C se preocupar com identificadores JavaScript não padrão.
21314 Keith Thompson
5
@KeithThompson Acho que confundi as perguntas e de alguma forma pensei que isso era sobre JavaScript, o que não faz sentido de qualquer maneira. Provavelmente já era tarde da noite.
panzi
9
Ou, para os mais desonestos entre nós: "true\0false"[(!x)*5]:-)
Esta resposta está fora do tópico e deve ser excluída, pois é sobre outro idioma que não o da pergunta.
Lundin
2
@Lundin Não concordo que isso deva ser excluído. O objetivo do SO não é apenas ajudar uma pessoa, mas ajudar todas as pessoas com a mesma pergunta. Quando procuro sprintf print boolean como true false c ++ , esta é a primeira página que aparece (embora, sem dúvida, essa página possa ter sido o resultado principal se essa resposta não existisse). Como C ++ é quase um superconjunto de C, não acho que essas respostas devam ser descartadas com tanta facilidade. +1 de mim.
Jeff G
1
@ Jeffff Sim, essas respostas devem ser excluídas, temos políticas muito claras. Leia as wikis das tags C e C ++. Esta pergunta não é útil para programadores de C, principalmente porque os sistemas booleanos de C e C ++ são completamente diferentes e a pergunta está marcada com C. O Google não é capaz de entender os dois ++ à direita em sua pesquisa não é um problema da SO.
Lundin
2
@Lundin Meu comentário não pretendia ser interpretado como um comentário sobre as políticas da SO. Foi realmente um comentário sobre se essa resposta adiciona construtivamente à pergunta. Esta resposta é imediatamente identificável como somente C ++. Ninguém vindo aqui para obter uma resposta somente C seria enganado a pensar que isso funcionaria em C e perderia tempo tentando. No entanto, esta é uma ótima resposta para C ++. Se as respostas são úteis, mesmo que não ajudem o OP, elas não devem ser mantidas? Acho que respostas construtivas que identificaram claramente advertências nunca devem ser excluídas, independentemente da política.
Jeff G
1
@JeffG Você pode acessá-lo em meta.stackoverflow.com , este não é o lugar para discussões.
Lundin
2
Para imprimir apenas 1 ou 0 com base no valor booleano que acabei de usar:
Isso é totalmente incompreensível. Levei um bom tempo antes de descobrir o que "false\0true"+6*xrealmente fazia. Se você trabalha em um projeto com outras pessoas ou apenas em um projeto com uma base de código que deseja entender x anos depois, construções como essa devem ser evitadas.
hellogoodbye
3
Embora eu veja que isso pode ser mais otimizado, pois é sem ramo. Se a velocidade é sua preocupação, isso pode ser uma opção, apenas certifique-se de explicar bem a mecânica por trás do truque em um comentário. Uma função embutida ou macro com um nome de auto-documentação também seria útil (mas provavelmente não suficiente neste caso).
hellogoodbye
3
Bem como as preocupações com urso legibilidade em mente que isso vai explodir se alguém passa em um valor diferente de 0 ou 1.
plugwash
2
@ plugwash É claro que você pode alterá-lo para o printf("%s\n","false\0true"+6*(x?1:0));que é apenas ... 5% menos legível.
precisa saber é o seguinte
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; } O mesmo que com static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }; apenas envolva-o em uma função com nome descritivo e não se preocupe com a legibilidade.
Respostas:
Não há especificador de formato para
bool
tipos. No entanto, como qualquer tipo de integrante menor que oint
promovidoint
quando transmitido aosprintf()
argumentos variados, você pode usar%d
:Mas porque não:
ou melhor:
ou, melhor ainda:
em vez de?
fonte
printf("%s", x ? "true" : "false");
resolveria o problema.printf("%s", x ? "true" : "false");
é melhor do que issoprintf(x ? "true" : "false");
- você está no controle total da cadeia de caracteres de formato aqui, para que não haja perigo de obter algo como o"%d"
que causaria problemas. Ofputs
, por outro lado, é uma opção melhor.fputs
"ainda melhor"? Estou sempre procurando maneiras de melhorar meu C. Em que circunstâncias devo usar emfputs
vez deprintf
?Não há especificador de formato para bool. Você pode imprimi-lo usando alguns dos especificadores existentes para imprimir tipos integrais ou fazer algo mais sofisticado:
fonte
bool
tipo em C, não apenas na edição C89 - é parte da especificação linguagem C99. Há uma nova palavra-chave_Bool
e, se você incluir<stdbool.h>
,bool
é sinônimo de_Bool
.O ANSI C99 / C11 não inclui um especificador de conversão extra para
bool
.Mas a biblioteca GNU C fornece uma API para adicionar especificadores personalizados .
Um exemplo:
Por se tratar de extensões glibc, o GCC alerta sobre esse especificador personalizado:
Resultado:
fonte
Na tradição de
itoa()
:fonte
btoa
é "string binária para a base da string 64" em JavaScript não padrão (Gecko e WebKit), portanto, convém usar um nome diferente."true\0false"[(!x)*5]
:-)!!x*5
.Você não pode, mas pode imprimir 0 ou 1
fonte
fonte
Se você gosta de C ++ melhor que C, pode tentar o seguinte:
fonte
Para imprimir apenas 1 ou 0 com base no valor booleano que acabei de usar:
Especialmente útil com bandeiras:
fonte
!!
pode ficar otimizadasPrefiro uma resposta da Melhor maneira de imprimir o resultado de um bool como 'false' ou 'true' em c? , Assim como
fonte
"false\0true"+6*x
realmente fazia. Se você trabalha em um projeto com outras pessoas ou apenas em um projeto com uma base de código que deseja entender x anos depois, construções como essa devem ser evitadas.printf("%s\n","false\0true"+6*(x?1:0));
que é apenas ... 5% menos legível.static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
O mesmo que comstatic inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; apenas envolva-o em uma função com nome descritivo e não se preocupe com a legibilidade.