@ Billinkc, pertanyaan saya sebenarnya bukan tentang apa cara terbaik untuk mencetak nilai bool - ini tentang specifier printf beton. Yang sepertinya tidak ada. Sudut lain untuk jawaban yang bagus adalah: mungkin ada cara untuk menambahkan
penentu
Cukup adil, meskipun saya tampaknya tidak memiliki kemampuan untuk melepaskan VtC jadi saya hanya harus menunggu suara saya berakhir.
billinkc
@maxschlepzig: satu-satunya cara untuk menyelesaikan masalah adalah dengan memeriksa dokumentasi. Jika Anda menggunakan GNU / Linux (misalnya, karena Anda tidak memberi tahu kami tentang sistem Anda), Anda dapat membaca manual printf terbaru di [Linux man pages] (man7.org). Jika Anda ingin mencetak string "benar" / "salah", Anda dapat membuatnya secara manual, itu sangat mudah.
Bulat M.
Jawaban:
711
Tidak ada penentu format untuk booljenis. Namun, karena jenis integral apa pun yang lebih pendek dari intyang dipromosikan intketika diturunkan ke printf()argumen variadik, Anda dapat menggunakan %d:
Saya akan memberi ini +1 jika Anda menyingkirkan ekspresi non-string-tunggal-literal sebagai string format. Penggunaan semacam ini dengan mudah berubah menjadi penggunaan yang tidak aman. printf("%s", x ? "true" : "false");akan memperbaiki masalah ini.
R .. GitHub BERHENTI MEMBANTU ICE
2
Untuk bagian "mengapa tidak" dari jawaban ini - penentu format untuk bool akan memungkinkan string format untuk digunakan seperti yang dirancang: untuk membangun string dengan campuran literal dan nilai.
noamtm
13
Hanya sebagai catatan, saya akan cenderung ke arah yang bersengketa yang printf("%s", x ? "true" : "false");adalah lebih baik bahwa printf(x ? "true" : "false");- Anda berada dalam keseluruhan kontrol dari format string di sini sehingga tidak ada bahaya bahwa itu akan mendapatkan sesuatu seperti "%d"yang akan menyebabkan masalah. Di fputssisi lain, ini adalah pilihan yang lebih baik.
paxdiablo
15
Mengapa fputs"lebih baik"? Saya selalu mencari cara untuk meningkatkan C. Saya dalam kondisi apa yang harus saya gunakan, fputsbukan printf?
Arc676
10
@ Arc676, untuk string tanpa pemformatan, fput lebih cepat dan lebih sederhana daripada printf (yang harus mengurai string mencari chars pemformatan). Menggunakan fput (stdout) alih-alih hanya menempatkan () (yang default ke stdout) menghilangkan baris baru yang menempatkan () ditambahkan ke output.
Chad
45
Tidak ada penentu format untuk bool. Anda dapat mencetaknya menggunakan beberapa specifier yang ada untuk mencetak tipe integral atau melakukan sesuatu yang lebih mewah:
@ H2CO3 lagian saya telah menyarankan solusi mencetak "benar" dan "salah" sebagai permintaan OP. Saya juga sedikit mengubah kata-kata saya pada bagian yang Anda sebutkan.
Ivaylo Strandjev
5
@IvayloStrandjev: Ya, ada adalah sebuah boolketik C, hanya saja tidak dalam edisi C89 - bagian itu dari C99 bahasa spec. Ada kata kunci baru _Bool, dan jika Anda sertakan <stdbool.h>, maka boolsinonim untuk _Bool.
Adam Rosenfield
30
ANSI C99 / C11 tidak termasuk specifier konversi printf tambahan untuk bool.
#include<stdio.h>#include<printf.h>#include<stdbool.h>staticint bool_arginfo(conststruct printf_info *info,size_t n,int*argtypes,int*size){if(n){
argtypes[0]= PA_INT;*size =sizeof(bool);}return1;}staticint bool_printf(FILE *stream,conststruct printf_info *info,constvoid*const*args){bool b =*(constbool*)(args[0]);int r = fputs(b ?"true":"false", stream);return r == EOF ?-1:(b ?4:5);}staticint 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)return1;bool b = argc >1;
r = printf("The result is: %B\n", b);
printf("(written %d characters)\n", r);return0;}
Karena ini merupakan ekstensi glibc, GCC memperingatkan tentang specifier khusus itu:
$ gcc -Wall -g main.c -o main
main.c: Dalam fungsi 'main':
main.c: 34: 3: peringatan: karakter tipe konversi yang tidak dikenal 'B' dalam format [-Wformat =]
r = printf ("Hasilnya adalah:% B \ n", b);
^
main.c: 34: 3: peringatan: terlalu banyak argumen untuk format [-Wformat-extra-args]
btoaadalah "string biner ke basis 64 string" dalam JavaScript non-standar (Gecko dan WebKit), jadi Anda mungkin ingin menggunakan nama yang berbeda.
panzi
26
@panzi: Saya tidak yakin itu sepadan dengan usaha seorang programmer C untuk khawatir tentang pengidentifikasi JavaScript non-standar.
Keith Thompson
5
@KeithThompson Saya pikir saya bingung dengan pertanyaan dan entah bagaimana berpikir ini tentang JavaScript, yang tidak masuk akal. Mungkin sudah larut malam.
panzi
9
Atau, untuk yang lebih licik di antara kita: "true\0false"[(!x)*5]:-)
paxdiablo
1
@ MoingDuck: mungkin !!x*5.
jxh
4
Anda tidak bisa, tetapi Anda dapat mencetak 0 atau 1
Jawaban ini di luar topik dan harus dihapus, karena ini tentang bahasa lain daripada yang ada di pertanyaan.
Lundin
2
@Lundin Saya tidak setuju bahwa ini harus dihapus. Tujuan SO tidak hanya untuk membantu satu orang, tetapi untuk membantu semua orang dengan pertanyaan yang sama. Ketika saya mencari sprintf print boolean sebagai true false c ++ , ini adalah halaman pertama yang muncul (walaupun bisa dibilang halaman ini mungkin merupakan hasil teratas jika jawaban ini tidak ada). Karena C ++ hampir merupakan superset dari C, saya tidak berpikir jawaban seperti itu harus dengan mudah dibuang. +1 dari saya.
Jeff G
1
@ JeffFF Ya jawaban seperti itu harus dihapus, kami memiliki kebijakan yang sangat jelas. Baca wiki tag C dan C ++. Pertanyaan ini tidak membantu programmer C terutama karena sistem boolean C dan C ++ sama sekali berbeda dan pertanyaannya ditandai C. Bahwa Google tidak dapat memahami dua trailing ++ dalam pencarian Anda bukan masalah SO.
Lundin
2
@Lundin Komentar saya tidak dimaksudkan untuk ditafsirkan sebagai komentar pada kebijakan SO. Itu benar-benar komentar tentang apakah jawaban ini menambah pertanyaan. Jawaban ini segera dapat diidentifikasi sebagai C ++ - saja. Tidak ada yang datang ke sini untuk jawaban C-only akan tertipu untuk berpikir ini akan berhasil di C dan membuang waktu untuk mencobanya. Namun, ini adalah jawaban yang bagus untuk C ++. Jika jawaban bermanfaat, bahkan jika mereka tidak membantu OP, maka bukankah seharusnya dijaga? Saya pikir jawaban konstruktif yang telah mengidentifikasi dengan jelas peringatan tidak boleh dihapus, terlepas dari kebijakan.
Jeff G
1
@JeffG Anda dapat memunculkannya di meta.stackoverflow.com , ini bukan tempat untuk melakukan diskusi ini.
Lundin
2
Untuk hanya mencetak 1 atau 0 berdasarkan nilai boolean saya hanya menggunakan:
Ini sama sekali tidak bisa dipahami. Butuh waktu yang lama sebelum saya menemukan apa yang "false\0true"+6*xsebenarnya terjadi. Jika Anda bekerja dalam proyek dengan orang lain, atau hanya dalam proyek dengan basis kode yang ingin Anda pahami x tahun kemudian, konstruksi seperti ini harus dihindari.
HelloGoodbye,
3
Meskipun saya melihat bahwa ini mungkin lebih dioptimalkan karena kurang cabang. Jika kecepatan menjadi perhatian Anda, ini mungkin menjadi pilihan, pastikan untuk menjelaskan mekanisme di balik trik dengan baik dalam komentar. Fungsi inline atau makro dengan nama yang mendokumentasikan diri juga akan membantu (tetapi mungkin tidak cukup dalam kasus ini).
HelloGoodbye,
3
Serta kekhawatiran tentang keterbacaan diingat bahwa ini akan meledak jika seseorang memberikan nilai selain 0 atau 1.
plugwash
2
@plugwash Anda tentu saja dapat mengubahnya printf("%s\n","false\0true"+6*(x?1:0));yang hanya ... 5% lebih sedikit dapat dibaca.
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; } Sama seperti dengan static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }; cukup bungkus dengan fungsi yang dinamai secara deskriptif dan jangan khawatir tentang keterbacaannya.
Jawaban:
Tidak ada penentu format untuk
bool
jenis. Namun, karena jenis integral apa pun yang lebih pendek dariint
yang dipromosikanint
ketika diturunkan keprintf()
argumen variadik, Anda dapat menggunakan%d
:Namun mengapa tidak:
atau lebih baik:
atau, bahkan lebih baik:
sebagai gantinya?
sumber
printf("%s", x ? "true" : "false");
akan memperbaiki masalah ini.printf("%s", x ? "true" : "false");
adalah lebih baik bahwaprintf(x ? "true" : "false");
- Anda berada dalam keseluruhan kontrol dari format string di sini sehingga tidak ada bahaya bahwa itu akan mendapatkan sesuatu seperti"%d"
yang akan menyebabkan masalah. Difputs
sisi lain, ini adalah pilihan yang lebih baik.fputs
"lebih baik"? Saya selalu mencari cara untuk meningkatkan C. Saya dalam kondisi apa yang harus saya gunakan,fputs
bukanprintf
?Tidak ada penentu format untuk bool. Anda dapat mencetaknya menggunakan beberapa specifier yang ada untuk mencetak tipe integral atau melakukan sesuatu yang lebih mewah:
sumber
bool
ketik C, hanya saja tidak dalam edisi C89 - bagian itu dari C99 bahasa spec. Ada kata kunci baru_Bool
, dan jika Anda sertakan<stdbool.h>
, makabool
sinonim untuk_Bool
.ANSI C99 / C11 tidak termasuk specifier konversi printf tambahan untuk
bool
.Tetapi pustaka GNU C menyediakan API untuk menambahkan penspesifikasi khusus .
Sebuah contoh:
Karena ini merupakan ekstensi glibc, GCC memperingatkan tentang specifier khusus itu:
Keluaran:
sumber
Dalam tradisi
itoa()
:sumber
btoa
adalah "string biner ke basis 64 string" dalam JavaScript non-standar (Gecko dan WebKit), jadi Anda mungkin ingin menggunakan nama yang berbeda."true\0false"[(!x)*5]
:-)!!x*5
.Anda tidak bisa, tetapi Anda dapat mencetak 0 atau 1
sumber
sumber
Jika Anda menyukai C ++ lebih baik daripada C, Anda dapat mencoba ini:
sumber
Untuk hanya mencetak 1 atau 0 berdasarkan nilai boolean saya hanya menggunakan:
Sangat berguna dengan Bendera:
sumber
!!
mungkin akan dioptimalkan jauhSaya lebih suka jawaban dari Cara terbaik untuk mencetak hasil bool sebagai 'salah' atau 'benar' dalam c? , seperti
sumber
"false\0true"+6*x
sebenarnya terjadi. Jika Anda bekerja dalam proyek dengan orang lain, atau hanya dalam proyek dengan basis kode yang ingin Anda pahami x tahun kemudian, konstruksi seperti ini harus dihindari.printf("%s\n","false\0true"+6*(x?1:0));
yang hanya ... 5% lebih sedikit dapat dibaca.static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Sama seperti denganstatic inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; cukup bungkus dengan fungsi yang dinamai secara deskriptif dan jangan khawatir tentang keterbacaannya.