Da ANSI C99 esiste _Bool
o bool
via stdbool.h
. Ma esiste anche un printf
identificatore di formato per bool?
Intendo qualcosa di simile a quello pseudo codice:
bool x = true;
printf("%B\n", x);
che stamperebbe:
true
Da ANSI C99 esiste _Bool
o bool
via stdbool.h
. Ma esiste anche un printf
identificatore di formato per bool?
Intendo qualcosa di simile a quello pseudo codice:
bool x = true;
printf("%B\n", x);
che stamperebbe:
true
Risposte:
Non esiste un identificatore di formato per i bool
tipi. Tuttavia, poiché qualsiasi tipo integrale più breve di quello che int
viene promosso int
quando trasmesso agli printf()
argomenti variadici, è possibile utilizzare %d
:
bool x = true;
printf("%d\n", x); // prints 1
Ma perchè no:
printf(x ? "true" : "false");
o meglio:
printf("%s", x ? "true" : "false");
o, ancora meglio:
fputs(x ? "true" : "false", stdout);
anziché?
printf("%s", x ? "true" : "false");
risolverebbe il problema.
printf("%s", x ? "true" : "false");
è meglio che printf(x ? "true" : "false");
- si è in totale controllo della stringa di formato qui quindi non c'è alcun pericolo che otterrà qualcosa di simile "%d"
che causerebbe problemi. La fputs
, d'altra parte, è una scelta migliore.
fputs
"ancora meglio"? Sono sempre alla ricerca di modi per migliorare il mio C. In quali circostanze dovrei usare fputs
invece di printf
?
Non esiste un identificatore di formato per bool. Puoi stamparlo usando alcuni degli identificatori esistenti per la stampa di tipi integrali o fare qualcosa di più fantasioso:
printf("%s", x?"true":"false");
bool
tipo in C, non solo nell'edizione C89 - è parte del linguaggio spec C99. C'è una nuova parola chiave _Bool
e, se includi <stdbool.h>
, bool
è sinonimo di _Bool
.
ANSI C99 / C11 non include un ulteriore identificatore di conversione printf per bool
.
Ma la libreria GNU C fornisce un'API per l'aggiunta di specificatori personalizzati .
Un esempio:
#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;
}
Dato che si tratta di estensioni glibc, GCC mette in guardia su tale identificatore personalizzato:
$ gcc -Wall -g main.c -o main main.c: nella funzione 'main': main.c: 34: 3: avviso: carattere del tipo di conversione sconosciuto 'B' nel formato [-Wformat =] r = printf ("Il risultato è:% B \ n", b); ^ main.c: 34: 3: avviso: troppi argomenti per il formato [-Wformat-extra-args]
Produzione:
$ ./main Il risultato è: falso (scritto 21 caratteri) $ ./main 1 Il risultato è: vero (scritto 20 caratteri)
Nella tradizione di itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
è "stringa binaria per basare 64 stringhe" in JavaScript non standard (Gecko e WebKit), quindi potresti voler usare un nome diverso.
"true\0false"[(!x)*5]
:-)
!!x*5
.
Se ti piace C ++ meglio di C, puoi provare questo:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Preferisco una risposta dal modo migliore per stampare il risultato di un bool come 'falso' o 'vero' in c? , proprio come
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
facesse davvero. Se lavori in un progetto con altre persone, o semplicemente in un progetto con una base di codice che vuoi capire x anni dopo, le costruzioni come questa devono essere evitate.
printf("%s\n","false\0true"+6*(x?1:0));
cui è solo ... il 5% in meno leggibile.
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Come con static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; basta avvolgerlo in una funzione con un nome descrittivo e non preoccuparti della sua leggibilità.