С 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 -o main main.c: в функции 'main': main.c: 34: 3: предупреждение: неизвестный символ типа преобразования "B" в формате [-Wformat =] r = printf («Результат:% B \ n», b); ^ main.c: 34: 3: предупреждение: слишком много аргументов для формата [-Wformat-extra-args]
Вывод:
$ ./main Результат: ложь (написано 21 символов) $ ./main 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;
Чтобы просто напечатать 1 или 0 на основе логического значения, которое я только что использовал:
printf("%d\n", !!(42));
Особенно полезно с флагами:
#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));
!!
может быть оптимизировано
Я предпочитаю ответ из Best way, чтобы напечатать результат 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; }
; просто оберните его в описательно названную функцию и не беспокойтесь о его удобочитаемости.