bool의 printf 형식 지정자는 무엇입니까?


457

ANSI C99 이후가 _Bool또는 bool를 통해 stdbool.h. 그러나 printfbool 의 형식 지정자 도 있습니까?

그 의사 코드와 같은 것을 의미합니다.

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

다음과 같이 인쇄됩니다.

true

1
자세한 내용은 cplusplus.com/reference/cstdio/printf 를 참조하십시오. 언제든지 만들 수 있습니다!
Varvarigos Emmanouil 2016


3
@ billinkc, 내 질문은 실제로 bool 값을 인쇄 하는 가장 좋은 방법 에 관한 것이 아니라 구체적인 printf 지정자에 관한 것입니다. 존재하지 않는 것 같습니다. 좋은 대답에 대한 또 다른 각도는 다음과 같습니다. 아마도 bool 변환을 수행하는 printf에 사용자 정의 형식 지정자를 추가하는 방법이있을 수 있습니다.
maxschlepzig

VtC를 언 캐스트 할 수는 없지만 투표가 만료 될 때까지 기다려야합니다.
billinkc 2016 년

@maxschlepzig : 문제를 해결하는 유일한 방법은 문서를 확인하는 것입니다. GNU / 리눅스를 사용하는 경우 (예를 들어 시스템에 대해 알려주지 않았으므로) [Linux man pages] (man7.org)에서 최신 printf 매뉴얼을 읽을 수 있습니다. "true"/ "false"문자열을 인쇄하려면 수동으로 생성 할 수 있습니다. 매우 쉽습니다.
Bulat M.

답변:


709

bool유형에 대한 형식 지정자가 없습니다 . 그러나 의 variadic 인수 로 전달 될 때보 다 짧은 정수 유형 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);

대신?


21
단일 문자열이 아닌 리터럴 표현식을 형식 문자열로 제거하면 +1합니다. 이러한 종류의 사용은 쉽게 안전하지 않은 사용으로 바뀝니다. printf("%s", x ? "true" : "false");문제를 해결할 것입니다.
R .. GitHub 중지 지원 얼음

2
이 답변의 "그렇지 않은"부분의 경우 bool의 형식 지정자를 사용하면 리터럴과 값이 혼합 된 문자열을 구성하기 위해 형식 문자열을 설계된대로 사용할 수 있습니다.
noamtm

13
그냥 참고로, 나는 분쟁으로 경향 것 printf("%s", x ? "true" : "false");입니다 더 나은 것을 printf(x ? "true" : "false");에서 당신이 - 그래서이없는 여기에 형식 문자열의 제어 에는 이 같은 것을 얻을거야 위험 "%d"문제를 일으킬 것이다는. 는 fputs, 다른 한편으로는, 이다 더 나은 옵션을 선택합니다.
paxdiablo 2013 년

15
fputs"더 나은"가요? 나는 항상 C를 향상시킬 수있는 방법을 찾고 있습니다. fputs대신 어떤 상황에서 사용해야 printf합니까?
Arc676

10
@ Arc676, 형식이없는 문자열의 경우 fputs는 printf보다 빠르며 간단합니다 (문자 형식을 찾는 문자열을 구문 분석해야 함). puts () (기본값은 stdout) 대신 fputs (stdout)를 사용하면 puts ()가 출력에 추가하는 줄 바꿈이 제거됩니다.
차드

45

bool의 형식 지정자는 없습니다. 정수 유형을 인쇄하기 위해 기존 지정자를 사용하여 인쇄하거나 더 멋진 작업을 수행 할 수 있습니다.

 printf("%s", x?"true":"false");

캐스트는 필요하지 않습니다.

@ H2CO3 어쨌든 OP 요청으로 "true"및 "false"를 인쇄하는 솔루션을 제안했습니다. 나는 또한 당신이 언급 한 부분에서 내 문구를 약간 변경했습니다.
Ivaylo Strandjev

5
@IvayloStrandjev : 네, 있습니다bool - C99 언어 사양의 그것의 부분 C의 유형, 그냥에서 C89 에디션. 이 새로운 키워드이다 _Bool, 당신은 포함 할 경우 <stdbool.h>, 다음 bool의 동의어입니다 _Bool.
Adam Rosenfield 2016 년

30

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-벽 -g main.c -o main
main.c : 기능 'main'에서 :
main.c : 34 : 3 : 경고 : [-Wformat =] 형식의 알 수없는 변환 유형 문자 'B'
   r = printf ( "결과 : % B \ n", b);
   ^
main.c : 34 : 3 : 경고 : 형식에 대한 인수가 너무 많습니다 [-Wformat-extra-args]

산출:

$ ./ 주
결과는 다음과 같습니다. false
(21 글자)
$ ./main 1
결과는 다음과 같습니다. true
(20 글자)

12

전통 itoa():

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

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

5
btoa비표준 JavaScript (Gecko 및 WebKit)에서 "이진 문자열에서 기본 64 문자열"이므로 다른 이름을 사용할 수 있습니다.
panzi

26
@ panzi : C 프로그래머가 비표준 JavaScript 식별자에 대해 걱정할 가치가 있다고 확신하지 않습니다.
Keith Thompson

5
@KeithThompson 질문을 혼란스럽게 생각하고 이것이 어쨌든 JavaScript에 관한 것이라고 생각했습니다. 아마 밤 늦었을 것입니다.
panzi 2016 년

9
또는, 우리 사이에 더 악독에 대한 : "true\0false"[(!x)*5]:-)
paxdiablo

1
@MooingDuck : 아마도 !!x*5.
jxh

4

할 수는 없지만 0 또는 1을 인쇄 할 수 있습니다

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

출처


2

C보다 C ++을 더 좋아한다면 다음을 시도해보십시오.

#include <ios>
#include <iostream>

bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;

5
이 답변은 주제에 맞지 않으므로 질문의 언어와 다른 언어에 관한 것이므로 삭제해야합니다.
Lundin

2
@Lundin 나는 이것이 삭제되어야한다는 것에 동의하지 않는다. SO의 목표는 한 사람을 돕는 것이 아니라 모든 사람이 같은 질문을하도록 돕는 것입니다. sprintf print boolean을 true false c ++로 검색하면 이것이 첫 번째 페이지입니다 ( 이 대답이 존재하지 않으면 이 페이지 가 최상위 결과 일 수는 있지만 ). C ++은 거의 C의 수퍼 세트이기 때문에 그러한 대답을 쉽게 버려야한다고 생각하지 않습니다. 나에게서 +1
Jeff G

1
@JeffG 예, 그러한 답변은 삭제해야합니다. 매우 명확한 정책이 있습니다. C 및 C ++ 태그 위키를 읽으십시오. 이 질문은 특히 C와 C ++ 부울 시스템이 완전히 다르고 질문에 C 태그가 붙어 있기 때문에 C 프로그래머에게는 도움이되지 않습니다 . Google이 검색에서 두 개의 후행 ++을 이해할 수 없다는 것은 SO의 문제가 아닙니다.
Lundin

2
@Lundin 내 의견은 SO 정책에 대한 의견으로 해석되지 않았습니다. 이 답변이 질문에 건설적으로 추가되는지 여부에 대한 의견이었습니다. 이 답변은 즉시 C ++ 전용으로 식별 할 수 있습니다. C 전용 답변을 위해 여기에 오는 사람은 이것이 C에서 효과가 있다고 생각하고 속이는 데 시간을 낭비하지 않습니다. 그러나 이것은 C ++에 대한 훌륭한 답변입니다. 영업에 도움이되지 않더라도 답변이 도움이된다면 보관하지 않아야합니까? 정책에 관계없이 경고를 명확하게 식별 한 건설적인 답변은 절대 삭제해서는 안된다고 생각합니다.
Jeff G

1
당신이 그것을 가져올 수 @JeffG meta.stackoverflow.com 이이 토론을 할 수있는 장소가 아니다.
Lundin

2

방금 사용한 부울 값을 기준으로 1 또는 0을 인쇄하려면 다음을 수행하십시오.

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

플래그와 함께 특히 유용합니다 :

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

이 있음을주의 !!멀리 최적화 얻을 수 있습니다
ragerdl

1

c에서 bool의 결과를 'false'또는 'true'로 인쇄하는 가장 좋은 방법 의 대답을 선호 합니까? , 처럼

printf("%s\n", "false\0true"+6*x);
  • x == 0, "false \ 0true"+ 0 ""false "를 의미합니다.
  • x == 1, "false \ 0true"+ 6 ""true "를 의미합니다.

21
이것은 완전히 이해할 수 없습니다. 내가 "false\0true"+6*x실제로 한 일을 알아 내기 전에는 시간이 많이 걸렸습니다 . 다른 사람들과 프로젝트를 진행하거나 x 년 후에 이해하기를 원하는 코드베이스 프로젝트에서 작업하는 경우 이와 같은 구성을 피해야합니다.
HelloGoodbye 2016 년

3
비록 이것이 분기가 없기 때문에 이것이 더 최적화 될 수 있음을 알았습니다. 속도가 걱정된다면, 이것은 선택 사항 일 수 있습니다. 트릭 뒤의 메커니즘을 주석으로 잘 설명하십시오. 자체 문서화 이름을 가진 인라인 함수 나 매크로도 도움이 될 것입니다 (그러나이 경우에는 충분하지 않을 수 있습니다).
HelloGoodbye 2016 년

3
가독성에 대한 우려뿐만 아니라 누군가가 0 또는 1 이외의 값을 전달하면 폭발 할 것이라는 점을 명심하십시오.
plugwash

2
@plugwash 물론 printf("%s\n","false\0true"+6*(x?1:0));읽을 수있는 5 %만으로 변경할 수 있습니다.
hoosierEE

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; }; 설명 적으로 명명 된 함수로 감싸서 가독성에 대해 걱정하지 마십시오.
yyny
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.