Da ANSI C99 esiste _Boolo boolvia stdbool.h. Ma esiste anche un printfidentificatore 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 _Boolo boolvia stdbool.h. Ma esiste anche un printfidentificatore 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 booltipi. Tuttavia, poiché qualsiasi tipo integrale più breve di quello che intviene promosso intquando 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 fputsinvece 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");
booltipo in C, non solo nell'edizione C89 - è parte del linguaggio spec C99. C'è una nuova parola chiave _Boole, 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*xfacesse 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à.