boolのprintf形式指定子とは何ですか?


458

ANSI C99以降、_Boolまたはboolを使用していstdbool.hます。しかしprintf、ブールのフォーマット指定子もありますか?

その疑似コードのようなものを意味します:

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

印刷されます:

true

1
詳細はcplusplus.com/reference/cstdio/printfを参照してください。いつでも作成できます。
Varvarigos Emmanouil 2013年


3
@billinkc、私の質問は実際にはブール値を印刷する最良の方法は何かについてではなく、具体的なprintf指定子についてです。存在しないようです。素敵な答えを別の角度は次のようになります。おそらくブール変換を行うのprintfにカスタム書式指定子を追加する方法があります...
maxschlepzig

十分に公平ですが、VtCをアンキャストする機能がないようですが、投票が期限切れになるまで待つ必要があります。
billinkc 2013年

@maxschlepzig:問題を解決する唯一の方法は、ドキュメントを確認することです。GNU / Linuxを使用している場合(例として、システムについて教えていないため)、[Linux manページ](man7.org)で最新のprintfマニュアルを読むことができます。「true」/「false」の文字列を印刷したい場合は、手動で作成できます。これは非常に簡単です。
Bulat M.16年

回答:


711

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);

代わりに?


21
フォーマット文字列として非単一文字列リテラル式を取り除く場合、これを+1します。この種の使用法は、安全でない使用法に簡単に変わります。printf("%s", x ? "true" : "false");問題を修正します。
R .. GitHub ICE HELPING ICEの停止2013年

2
この回答の「理由」の部分については、boolのフォーマット指定子を使用すると、フォーマット文字列を設計どおりに使用できます。リテラルと値が混在する文字列を作成するためです。
noamtm 2014

13
ちょうどメモとして、私printf("%s", x ? "true" : "false");はそれより優れていることに異議を唱える傾向がありprintf(x ? "true" : "false");ます- ここでフォーマット文字列を完全に制御できるので、問題を引き起こすようなものを取得する危険はありません"%d"fputs一方、あるより良いオプション。
paxdiablo 2014年

15
なぜfputs「さらに良い」のですか?私は常に私のCを改善する方法を探しています。どのような状況でfputs代わりに使用する必要がありprintfますか?
Arc676

10
@ Arc676、フォーマットされていない文字列の場合、fputsはprintf(フォーマット文字を探すために文字列を解析する必要がある)よりも高速で単純です。puts()(デフォルトはstdout)だけでなくfputs(stdout)を使用すると、puts()が出力に追加する改行が削除されます。
Chad

45

boolにはフォーマット指定子はありません。整数型を印刷するための既存の指定子のいくつかを使用してそれを印刷したり、より豪華なことをしたりできます。

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

キャストは必要ありません。

@ H2CO3とにかく、OPリクエストとして「true」と「false」を出力するソリューションを提案しました。また、あなたが言及する部分の表現を少し変更しました。
Ivaylo Strandjev 2013年

5
@IvayloStrandjev:はい、そこにあるbool - C99言語仕様のそれの一部Cを入力し、ちょうどないでC89版は。新しいキーワードがあり_Boolます。を含める<stdbool.h>と、boolはの同意語になり_Boolます。
アダムローゼンフィールド2013年

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 -Wall -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文字書かれています)
$ ./メイン1
結果は次のとおりです。
(20文字書いてあります)

12

の伝統ではitoa()

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

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

5
btoa非標準のJavaScript(GeckoおよびWebKit)では「バイナリ文字列からベース64文字列へ」であるため、別の名前を使用することをお勧めします。
panzi 2013年

26
@panzi:Cプログラマーが非標準のJavaScript識別子について心配する努力をする価値があるかどうかはわかりません。
キース・トンプソン、

5
@KeithThompson私は質問を混乱させたと思うし、どういうわけかこれはJavaScriptに関するものだと思った。おそらく深夜だった。
パンジ14年

9
または、私たちの間でより"true\0false"[(!x)*5]
悪質

1
@MooingDuck:たぶん!!x*5
jxh


2

CよりC ++が好きなら、これを試すことができます。

#include <ios>
#include <iostream>

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

5
この回答はトピックから外れており、質問の言語とは別の言語に関するものであるため、削除する必要があります。
ランディン2018

2
@Lundinこれを削除すべきだとは思わない。SOの目標は、1人の人を助けるだけでなく、同じ質問を持つすべての人を助けることです。私がsprintf print booleanをtrue false c ++として検索すると、これが最初に表示されるページです(ただし、この答えが存在しない場合、おそらくこのページがトップの結果だった可能性があります)。C ++はCのスーパーセットに近いので、そのような答えを簡単に破棄できるとは思いません。私からの+1。
ジェフG

1
@JeffGはい、そのような答えは削除する必要があります。非常に明確なポリシーがあります。CおよびC ++タグのwikiを読んでください。CとC ++のブールシステムはまったく異なり、質問にはCというタグが付けられているため、この質問はCプログラマにとって特に役に立ちません。Googleが検索の末尾の2つの++を理解できないことは、SOの問題ではありません。
ランディン

2
@Lundin私のコメントは、SOのポリシーに関するコメントとして解釈されることを意図していませんでした。これは、この回答が建設的に質問に追加されるかどうかについてのコメントでした。この回答は、C ++のみとしてすぐに識別できます。Cのみの回答を求めてここに来る人はだれも、これがCで機能し、それを試すのに時間を浪費するだろうと思い込まされません。しかし、これはC ++にとって素晴らしい答えです。回答が役立つ場合、たとえそれがOPに役立たない場合でも、それらは保持されるべきではありませんか?ポリシーに関係なく、注意事項を明確に示した建設的な回答は削除しないでください。
Jeff G

1
あなたが上でそれを持ち出すことができ@JeffG meta.stackoverflow.com、これはこの議論を持っている場所ではありません。
ランディン

2

使用したブール値に基づいて1または0を出力するには、次のようにします。

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

フラグを使用すると特に便利です。

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

その!!可能性がすぐに最適化されることに注意してください
ragerdl '11 / 09/19

1

bの結果をcで「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 2015年

3
ブランチがないので、もっと最適化されているかもしれませんが。速度が気になる場合、これはオプションかもしれませんが、トリックの背後にあるメカニズムをコメントでよく説明してください。自己記述的な名前のインライン関数またはマクロも役立ちます(ただし、この場合はおそらく十分ではありません)。
HelloGoodbye 2015年

3
読みやすさに関する懸念と同様に、誰かが0または1以外の値を渡した場合、これは爆発することに
注意してください

2
@plugwashもちろん、変更することもできますが、printf("%s\n","false\0true"+6*(x?1:0));それは... 5%読みにくくなります。
hoosierEE 2015年

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 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.