Bool için printf format belirleyici nedir?


458

ANSI C99 yana olduğunu _Boolveya boolüzeri stdbool.h. Ancak printfbool için bir format belirleyici var mı?

Bu sözde kod gibi bir şey demek istiyorum:

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

yazdırılacak olan:

true

1
Daha fazla bilgi için bunu okuyabilirsiniz cplusplus.com/reference/cstdio/printf Her zaman yapabilirsiniz!
Varvarigos Emmanouil


3
@billinkc, sorum gerçekten bool değerlerini yazdırmanın en iyi yolu hakkında değil, somut bir printf belirleyicisiyle ilgili. Hangi var gibi görünmüyor. Güzel bir cevaba başka bir açı olurdu: belki
boole

Yeterince adil, her ne kadar VtC uncast yeteneğine sahip gibi görünmüyor, bu yüzden sadece benim oyumun süresinin dolmasını beklemek zorunda kalacağım.
billinkc

@maxschlepzig: sorunu çözmenin tek yolu belgeleri kontrol etmektir. GNU / Linux kullanıyorsanız (örneğin, bize sisteminizden bahsetmediğiniz için), [Linux man sayfalarında] (man7.org) güncel bir printf kılavuzunu okuyabilirsiniz. "True" / "false" dizgilerinin basılmasını istiyorsanız, bunları manuel olarak oluşturabilirsiniz, oldukça kolaydır.
Bulat M.

Yanıtlar:


711

Türler için biçim belirteci yoktur bool. Ancak, varyasyon argümanlarına aktarıldığında inttanıtıldığından daha kısa olan herhangi bir integral türü şunları kullanabilirsiniz :intprintf()%d

bool x = true;
printf("%d\n", x); // prints 1

Ama neden olmasın:

printf(x ? "true" : "false");

ya da daha iyisi:

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

veya daha da iyisi:

fputs(x ? "true" : "false", stdout);

yerine?


21
Biçim dizesi olarak tek-dize-değişmez ifadesinden kurtulursanız bunu + 1'leyeceğim. Bu tür kullanım kolayca güvenli olmayan kullanıma dönüşür. printf("%s", x ? "true" : "false");sorunu çözer.
R .. GitHub DURDURMAK BUZA YARDIMCI

2
Bu cevabın "neden olmasın" kısmı için - bool için bir format belirleyici, format dizesinin tasarlandığı gibi kullanılmasına izin verir: değişmez değerler ve değerlerin bir karışımıyla bir dize oluşturmak için.
noamtm

13
Sadece bir not olarak, bu printf("%s", x ? "true" : "false");daha iyi tartışmaya eğilimi olacaktır printf(x ? "true" : "false");- burada biçim dizesinin tam kontrolü altındasınız, bu yüzden sorunlara neden olacak bir şey elde etme tehlikesi yoktur"%d" . fputsÖte yandan, bir daha iyi bir seçenek.
paxdiablo

15
fputs" Neden daha iyi"? Her zaman C'mi geliştirmenin yollarını arıyorum. Hangi koşullar fputsyerine kullanmalıyım printf?
Arc676

10
@ Arc676, biçimlendirmesi olmayan bir dize için fputs, printf'den (biçimlendirme karakterleri arayan dizeyi ayrıştırmak zorundadır) daha hızlı ve basittir. Sadece puts () (varsayılan olarak stdout) yerine fputs (stdout) kullanılması, puts () işlevinin çıktıya eklediği yeni satırı ortadan kaldırır.
Çad

45

Bool için format belirleyici yok. Entegre türleri yazdırmak için mevcut belirteçlerden bazılarını kullanarak yazdırabilir veya daha süslü bir şey yapabilirsiniz:

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

Oyuncular gerekli değildir.

@ H2CO3 zaten OP istekleri olarak "true" ve "false" yazdırma için bir çözüm önerdim. Ayrıca bahsettiğiniz kısımdaki ifadelerimi biraz değiştirdim.
Ivaylo Strandjev

5
@IvayloStrandjev: Evet, olan bir bool- C99 dil spec 's parçası C tipi, sadece değil C89 baskı. Yeni bir anahtar kelime var _Boolve eklerseniz <stdbool.h>, booleşanlamlıdır _Bool.
Adam Rosenfield

30

ANSI C99 / C11 için fazladan bir printf dönüşüm belirteci içermez bool.

Ancak GNU C kütüphanesi, özel tanımlayıcılar eklemek için bir API sağlar .

Bir örnek:

#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;
}

Bir glibc uzantısı olduğundan GCC bu özel belirleyici hakkında uyarır:

$ gcc -Duvar -g main.c -o ana
main.c: 'main' işlevinde:
main.c: 34: 3: uyarı: [-Wformat =] biçiminde bilinmeyen dönüşüm türü karakter 'B'
   r = printf ("Sonuç:% B \ n", b);
   ^
main.c: 34: 3: uyarı: biçim için çok fazla argüman [-Wformat-extra-args]

Çıktı:

$ ./main
Sonuç: yanlış
(yazılı 21 karakter)
$ ./alan 1
Sonuç: doğru
(yazılı 20 karakter)

12

Geleneğinde itoa():

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

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

5
btoastandart olmayan JavaScript'te (Gecko ve WebKit) "binary string to base 64 string" dir, bu nedenle farklı bir ad kullanmak isteyebilirsiniz.
panzi

26
@panzi: Bir C programcısının standart olmayan JavaScript tanımlayıcıları hakkında endişelenmesine değdiğinden emin değilim.
Keith Thompson

5
@KeithThompson Sanırım soruları karıştırdım ve bir şekilde bunun JavaScript ile ilgili olduğunu düşündüm, bu da hiçbir anlam ifade etmiyor. Muhtemelen gece geç kalmıştı.
Mart'ta panzi

9
Veya aramızdaki daha dolambaçlılar için: "true\0false"[(!x)*5]:-)
paxdiablo

1
@MooingDuck: belki !!x*5.
jxh

4

Yapamazsınız, ancak 0 veya 1 yazdırabilirsiniz

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

kaynak


2

C ++ 'dan C'den daha iyi isterseniz, bunu deneyebilirsiniz:

#include <ios>
#include <iostream>

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

5
Bu cevap konu dışıdır ve sorudaki dilden başka bir dil ile ilgili olduğu için silinmelidir.
Lundin

2
@Lundin Bunun silinmesi gerektiğine katılmıyorum. SO'nun amacı sadece bir kişiye değil aynı soruya sahip tüm insanlara yardım etmektir. Sprintf print boolean'ı true false c ++ olarak aradığımda , bu ortaya çıkan ilk sayfadır ( bu cevap yoksa, muhtemelen bu sayfa en iyi sonuç olabilir). C ++ neredeyse C'nin bir üst kümesi olduğundan, bu tür cevapların bu kadar kolay atılması gerektiğini düşünmüyorum. Benden +1.
Jeff G

1
@JeffG Evet, bu tür cevaplar silinmeli, çok açık politikalarımız var. C ve C ++ etiket wikilerini okuyun. Bu soru C programcıları için özellikle yararlı değildir çünkü C ve C ++ boolean sistemleri tamamen farklıdır ve soru C olarak etiketlenmiştir. Google, aramanızdaki iki arka ++ işaretini anlayamaz.
Lundin

2
@Lundin Benim yorumum SO'nun politikaları hakkında yorum olarak yorumlanmayı amaçlamıyordu. Bu cevabın soruya yapıcı bir şekilde katkıda bulunup bulunmadığı hakkında bir yorum yapıldı. Bu cevap hemen yalnızca C ++ olarak tanımlanabilir. Buraya sadece C cevabı için gelen kimse, bunun C'de işe yarayacağını düşünmeye kandırılmayacak ve denemek için zaman harcayacaktır. Ancak, bu C ++ için harika bir cevaptır. Cevaplar faydalıysa, OP'ye yardımcı olmasalar bile, o zaman tutulmamalıdır mı? Politika ne olursa olsun, uyarıları açıkça tanımlayan yapıcı cevapların asla silinmemesi gerektiğini düşünüyorum.
Jeff G

1
@JeffG Meta.stackoverflow.com adresinde bulabilirsiniz , bu tartışmanın yapıldığı yer burası değil.
Lundin

2

Az önce kullandığım boolean değerine göre 1 veya 0 yazdırmak için:

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

Özellikle Bayraklarda kullanışlıdır:

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


1

Ben bir bool sonucu 'yanlış' veya 'true' olarak yazdırmak için En iyi yolu bir cevap tercih ? , tıpkı

printf("%s\n", "false\0true"+6*x);
  • x == 0, "false \ 0true" + 0 "," false "anlamına gelir;
  • x == 1, "false \ 0true" + 6 "," doğru "anlamına gelir;

21
Bu tamamen anlaşılmaz. "false\0true"+6*xGerçekten ne yaptığını anlayabilmem biraz zamanımı aldı . Başka insanlarla bir projede veya sadece x yıl sonra anlamak istediğiniz bir kod tabanındaki bir projede çalışıyorsanız , bunun gibi yapılardan kaçınılmalıdır.
HelloGoodbye

3
Her ne kadar şubesiz olduğu için bunun daha optimize olabileceğini görmeme rağmen. Hız endişenizse, bu bir seçenek olabilir, sadece bir yorumda hilenin arkasındaki mekaniği açıkladığınızdan emin olun. Kendi kendini belgeleyen ada sahip bir satır içi işlev veya makro da yardımcı olabilir (ancak bu durumda muhtemelen yeterli değildir).
HelloGoodbye

3
Okunabilirlikle ilgili endişelerin yanı sıra, biri 0 veya 1'den başka bir değerden geçerse bunun patlayacağını aklınızda bulundurun.
plugwash

2
@plugwash Elbette bunu değiştirebilirsiniz printf("%s\n","false\0true"+6*(x?1:0));...% 5 daha az okunabilir.
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; } İle aynı static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }; sadece tanımlayıcı olarak adlandırılmış bir işleve sarın ve okunabilirliği konusunda endişelenmeyin.
yyny
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.