Desde ANSI C99, existe _Bool
ou bool
via stdbool.h
. Mas há também um printf
especificador de formato para bool?
Quero dizer algo como nesse pseudo código:
bool x = true;
printf("%B\n", x);
que imprimiria:
true
Desde ANSI C99, existe _Bool
ou bool
via stdbool.h
. Mas há também um printf
especificador de formato para bool?
Quero dizer algo como nesse pseudo código:
bool x = true;
printf("%B\n", x);
que imprimiria:
true
Respostas:
Não há especificador de formato para bool
tipos. No entanto, como qualquer tipo de integrante menor que o int
promovido int
quando transmitido aos printf()
argumentos variados, você pode usar %d
:
bool x = true;
printf("%d\n", x); // prints 1
Mas porque não:
printf(x ? "true" : "false");
ou melhor:
printf("%s", x ? "true" : "false");
ou, melhor ainda:
fputs(x ? "true" : "false", stdout);
em vez de?
printf("%s", x ? "true" : "false");
resolveria o problema.
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.
fputs
"ainda melhor"? Estou sempre procurando maneiras de melhorar meu C. Em que circunstâncias devo usar em fputs
vez de printf
?
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:
printf("%s", x?"true":"false");
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:
#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;
}
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)
Na tradição de itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
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
.
Se você gosta de C ++ melhor que C, pode tentar o seguinte:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Prefiro uma resposta da Melhor maneira de imprimir o resultado de um bool como 'false' ou 'true' em c? , Assim como
printf("%s\n", "false\0true"+6*x);
"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 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.