Оскільки 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; }; просто загорніть його в описово названу функцію і не хвилюйтеся з приводу її читабельності.