Od ANSI C99 jest _Bool
lub bool
przez stdbool.h
. Ale czy istnieje również printf
specyfikator formatu dla bool?
Mam na myśli coś takiego w tym pseudo kodzie:
bool x = true;
printf("%B\n", x);
który wydrukowałby:
true
Od ANSI C99 jest _Bool
lub bool
przez stdbool.h
. Ale czy istnieje również printf
specyfikator formatu dla bool?
Mam na myśli coś takiego w tym pseudo kodzie:
bool x = true;
printf("%B\n", x);
który wydrukowałby:
true
Odpowiedzi:
Nie ma specyfikatora formatu dla bool
typów. Ponieważ jednak dowolny typ całkowy krótszy niż int
promowany, int
gdy jest przekazywany do printf()
argumentów variadic, możesz użyć %d
:
bool x = true;
printf("%d\n", x); // prints 1
Ale dlaczego nie:
printf(x ? "true" : "false");
albo lepiej:
printf("%s", x ? "true" : "false");
lub nawet lepiej:
fputs(x ? "true" : "false", stdout);
zamiast?
printf("%s", x ? "true" : "false");
rozwiązałoby problem.
printf("%s", x ? "true" : "false");
jest lepiej , że printf(x ? "true" : "false");
- jesteś w całkowitej kontroli ciągu formatu tutaj więc nie ma żadnego niebezpieczeństwa, że będzie to coś jak "%d"
które mogłyby powodować problemy. Z fputs
drugiej strony jest lepszym rozwiązaniem.
fputs
„jeszcze lepiej”? Zawsze szukam sposobów na poprawę mojego C. W jakich okolicznościach powinienem stosować fputs
zamiast printf
?
Nie ma specyfikatora formatu dla bool. Możesz wydrukować go za pomocą niektórych istniejących specyfikatorów do drukowania typów całkowitych lub zrobić coś bardziej wymyślnego:
printf("%s", x?"true":"false");
bool
typ w C, nie tylko w wersji C89 - to część języka specyfikacji C99. Pojawiło się nowe słowo kluczowe _Bool
, a jeśli je podasz <stdbool.h>
, bool
to synonim _Bool
.
ANSI C99 / C11 nie zawierają dodatkowego specyfikatora konwersji printf dla bool
.
Ale biblioteka GNU C zapewnia interfejs API do dodawania niestandardowych specyfikatorów .
Przykład:
#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;
}
Ponieważ jest to rozszerzenie glibc, GCC ostrzega przed tym niestandardowym specyfikatorem:
$ gcc -Wall -g main.c -o main main.c: W funkcji „main”: main.c: 34: 3: ostrzeżenie: nieznany typ konwersji znak „B” w formacie [-Wformat =] r = printf („Wynikiem jest:% B \ n”, b); ^ main.c: 34: 3: ostrzeżenie: zbyt wiele argumentów dla formatu [-Wformat-extra-args]
Wynik:
$ ./main Wynik jest następujący: false (napisane 21 znaków) $ ./main 1 Wynik jest następujący: prawda (napisano 20 znaków)
W tradycji itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
to „ciąg binarny do podstawowego ciągu 64” w niestandardowym JavaScript (Gecko i WebKit), więc możesz chcieć użyć innej nazwy.
"true\0false"[(!x)*5]
:-)
!!x*5
.
Jeśli podoba Ci się C ++ lepiej niż C, możesz spróbować:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Wolę odpowiedź od najlepszego sposobu, aby wydrukować wynik bool jako „fałsz” lub „prawda” w c? , tak jak
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
sporo czasu, zanim zorientowałem się, co naprawdę zrobiłem. Jeśli pracujesz w projekcie z innymi ludźmi lub po prostu w projekcie z bazą kodu, którą chcesz zrozumieć x lata później, należy unikać takich konstrukcji.
printf("%s\n","false\0true"+6*(x?1:0));
który jest tylko ... 5% mniej czytelny.
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Taki sam jak z static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; po prostu zawiń ją w funkcję o nazwie opisowej i nie martw się o jej czytelność.