Оскільки ANSI C99 є _Bool
або bool
через stdbool.h
. Але чи є також printf
специфікатор формату для bool?
Я маю на увазі щось на кшталт цього псевдокоду:
bool x = true;
printf("%B\n", x);
що друкувало б:
true
Оскільки ANSI C99 є _Bool
або bool
через stdbool.h
. Але чи є також printf
специфікатор формату для bool?
Я маю на увазі щось на кшталт цього псевдокоду:
bool x = true;
printf("%B\n", x);
що друкувало б:
true
Відповіді:
Не існує специфікатора формату для bool
типів. Однак, оскільки будь-який інтегральний тип коротший, ніж int
рекламується int
при printf()
переході до різних варіантів, ви можете використовувати %d
:
bool x = true;
printf("%d\n", x); // prints 1
Але чому б і ні:
printf(x ? "true" : "false");
або, ще краще:
printf("%s", x ? "true" : "false");
або, ще краще:
fputs(x ? "true" : "false", stdout);
натомість?
printf("%s", x ? "true" : "false");
вирішив би це питання.
printf("%s", x ? "true" : "false");
це краще , що printf(x ? "true" : "false");
ви - в загальному контролі рядки формату тут , тому немає ні небезпеки , що він буде отримувати що - щось подібне , "%d"
яке викликало б проблеми. З fputs
іншого боку, це кращий варіант.
fputs
"ще краще"? Я завжди шукаю способів покращити свій C. За яких обставин слід використовувати fputs
замість цього printf
?
Не існує специфікатора формату для bool. Ви можете роздрукувати його за допомогою деяких існуючих специфікаторів для друку інтегральних типів або зробити щось більш фантазійне:
printf("%s", x?"true":"false");
bool
типу в C, але тільки не в C89 видання - це частина мови специфікації C99. Існує нове ключове слово _Bool
, і якщо ви включите <stdbool.h>
, то bool
це синонім для _Bool
.
ANSI C99 / C11 не включає додатковий специфікатор перетворення printf для bool
.
Але бібліотека GNU C пропонує API для додавання спеціальних специфікаторів .
Приклад:
#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;
}
Оскільки це розширення glibc, GCC попереджає про цей спеціальний специфікатор:
$ gcc -Wall -g main.c -о головний main.c: У функції 'main': main.c: 34: 3: попередження: невідомий символ типу конверсії "B" у форматі [-Wformat =] r = printf ("Результат:% B \ n", b); ^ main.c: 34: 3: попередження: занадто багато аргументів для формату [-Wformat-extra-args]
Вихід:
$ ./ головна Результат: хибний (написано 21 символ) $ ./ головна 1 Результат: правда (написано 20 символів)
У традиції itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
є "бінарний рядок до бази 64 рядка" в нестандартному JavaScript (Gecko та WebKit), тому ви, можливо, захочете використовувати інше ім'я.
"true\0false"[(!x)*5]
:-)
!!x*5
.
Якщо вам подобається C ++ краще, ніж C, ви можете спробувати це:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Я вважаю за краще відповідь від Найкращий спосіб надрукувати результат bool як "false" або "true" в c? , так як
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
насправді зробив. Якщо ви працюєте в проекті з іншими людьми або просто в проекті з кодовою базою, яку ви хочете зрозуміти через x років, подібних конструкцій слід уникати.
printf("%s\n","false\0true"+6*(x?1:0));
який є лише ... 5% менш читабельним.
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Те саме, що і з static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; просто загорніть його в описово названу функцію і не хвилюйтеся з приводу її читабельності.