Что такое спецификатор формата printf для bool?

274

Поскольку ANSI C99 имеет _Bool или bool через stdbool.h. Но существует ли спецификатор формата printf для bool?

Я имею в виду что-то вроде этого псевдокода:

bool x = true;
printf("%B\n", x);

который будет печатать:

true
  • 1
    Вы можете прочитать это для получения дополнительной информации cplusplus.com/reference/cstdio/printf Вы всегда можете сделать это, хотя!
Показать ещё 3 комментария
Теги:
printf

8 ответов

402
Лучший ответ

Нет. Но так как любой целочисленный тип короче 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);

вместо

  • 13
    Я бы добавил +1, если вы избавитесь от выражения, не являющегося строковым литералом, в качестве строки формата. Этот вид использования легко превращается в небезопасное использование. printf("%s", x ? "true" : "false"); бы решить проблему.
  • 2
    Для части «почему нет» этого ответа - спецификатор формата для bool позволил бы использовать форматную строку, как задумано: для создания строки со смесью литералов и значений.
Показать ещё 10 комментариев
26

Нет спецификатора формата для bool. Вы можете распечатать его, используя некоторые из существующих спецификаций для печати интегральных типов или сделать что-то более фантастическое:

 printf("%s", x?"true":"false");
  • 0
    Актерский состав не нужен.
  • 0
    @ H2CO3 В любом случае я предложил решение, печатающее «true» и «false» в качестве запросов OP. Я также немного изменил свою формулировку в части, которую вы упоминаете.
Показать ещё 2 комментария
23

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: In function ‘main’:
main.c:34:3: warning: unknown conversion type character ‘B’ in format [-Wformat=]
   r = printf("The result is: %B\n", b);
   ^
main.c:34:3: warning: too many arguments for format [-Wformat-extra-args]

Вывод:

$ ./main
The result is: false
(written 21 characters)
$ ./main 1
The result is: true
(written 20 characters)
7

В традиции itoa():

#define btoa(x) ((x)?"true":"false")

bool x = true;
printf("%s\n", btoa(x));
  • 4
    btoa нестандартном JavaScript (Gecko и WebKit) btoa - это «строка от двоичной до базовой строки 64», поэтому вы можете использовать другое имя.
  • 24
    @panzi: Я не уверен, что программисту Си стоит потрудиться беспокоиться о нестандартных идентификаторах JavaScript.
Показать ещё 9 комментариев
2

Если вам нравится С++ лучше, чем C, вы можете попробовать следующее:

#include <ios>
#include <iostream>

bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
  • 2
    Этот ответ не по теме и должен быть удален, поскольку речь идет о другом языке, чем тот, который указан в вопросе.
  • 0
    @ Лундин Я не согласен, что это должно быть удалено. Цель SO - не просто помочь одному человеку, но помочь всем людям с одним и тем же вопросом. Когда я ищу sprintf print boolean как true false c ++ , это первая страница, которая появляется (хотя, возможно, эта страница могла быть лучшим результатом, если этот ответ не существовал). Поскольку C ++ является почти надмножеством C, я не думаю, что такие ответы следует так легко отбрасывать. +1 от меня.
Показать ещё 3 комментария
2

Я предпочитаю ответ от Лучший способ напечатать результат bool как "false" или "true" в c?, точно так же, как

printf("%s\n", "false\0true"+6*x);
  • x == 0, "false\0true" + 0 "означает "false";
  • x == 1, "false\0true" + 6 "означает "true";
  • 17
    Это совершенно непостижимо. Мне потребовалось некоторое время, прежде чем я понял, что на самом деле сделал "false\0true"+6*x . Если вы работаете в проекте с другими людьми или просто в проекте с базой кода, которую вы хотите понять спустя x лет, таких конструкций следует избегать.
  • 3
    Хотя я вижу, что это может быть более оптимизировано, поскольку оно не требует ответвлений. Если вам важна скорость, это может быть вариант, просто обязательно объясните механику, стоящую за этим трюком, в комментарии. Встроенная функция или макрос с самодокументируемым именем также были бы полезны (но, вероятно, не достаточны в этом случае).
Показать ещё 3 комментария
2

Вы не можете, но вы можете печатать 0 или 1

_Bool b = 1;
printf("%d\n", b);

источник

0

Чтобы просто напечатать 1 или 0 на основе логического значения, которое я использовал:

printf("%d\n", !!(42));

Особенно полезно с флагами:

#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню