ตั้งแต่ ANSI C99 มี_Bool
หรือผ่านทางbool
stdbool.h
แต่จะมีตัวprintf
ระบุรูปแบบสำหรับบูลด้วยหรือไม่
ฉันหมายถึงบางอย่างเช่นในรหัสหลอกว่า:
bool x = true;
printf("%B\n", x);
ซึ่งจะพิมพ์:
true
ตั้งแต่ ANSI C99 มี_Bool
หรือผ่านทางbool
stdbool.h
แต่จะมีตัวprintf
ระบุรูปแบบสำหรับบูลด้วยหรือไม่
ฉันหมายถึงบางอย่างเช่นในรหัสหลอกว่า:
bool x = true;
printf("%B\n", x);
ซึ่งจะพิมพ์:
true
คำตอบ:
ไม่มีตัวระบุรูปแบบสำหรับ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);
แทน?
printf("%s", x ? "true" : "false");
จะแก้ไขปัญหา
printf("%s", x ? "true" : "false");
เป็นดีกว่าว่าprintf(x ? "true" : "false");
- คุณอยู่ในรวมการควบคุมของสตริงรูปแบบที่นี่จึงมีไม่มีอันตรายว่ามันจะได้รับสิ่งที่ต้องการ"%d"
ที่จะทำให้เกิดปัญหา fputs
บนมืออื่น ๆ ที่เป็นตัวเลือกที่ดี
fputs
"ดียิ่งขึ้น"? ฉันมักจะมองหาวิธีการปรับปรุงซีภายใต้สถานการณ์ของฉันสิ่งที่ฉันควรใช้fputs
แทนprintf
?
ไม่มีตัวระบุรูปแบบสำหรับบูล คุณสามารถพิมพ์โดยใช้ specifiers ที่มีอยู่บางตัวเพื่อพิมพ์ integral type หรือทำสิ่งที่แฟนซีมากขึ้น:
printf("%s", x?"true":"false");
bool
ประเภทใน C เพียงแค่ไม่ได้อยู่ในรุ่น C89 - การเป็นส่วนหนึ่งของมันของสเปคภาษา C99 มีคำหลักใหม่เป็น_Bool
และถ้าคุณรวม<stdbool.h>
แล้วเป็นคำพ้องสำหรับbool
_Bool
ANSI C99 / C11 ไม่ได้มีระบุ printf bool
แปลงพิเศษสำหรับ
แต่ห้องสมุด GNU C มี API สำหรับการเพิ่ม specifiers
ตัวอย่าง:
#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: คำเตือน: ไม่รู้จักอักขระประเภทการแปลง 'B' ในรูปแบบ [- รูปแบบ =] r = printf ("ผลลัพธ์คือ:% B \ n", b); ^ main.c: 34: 3: คำเตือน: มีอาร์กิวเมนต์มากเกินไปสำหรับรูปแบบ [- รูปแบบ - ส่วนเสริมพิเศษ]
เอาท์พุท:
$ ./main ผลลัพธ์คือ: false (เขียน 21 ตัวอักษร) $ ./main 1 ผลลัพธ์คือ: จริง (เขียน 20 ตัวอักษร)
ในประเพณีของitoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
คือ "สตริงไบนารีถึงเบส 64 สตริง" ใน JavaScript ที่ไม่ได้มาตรฐาน (Gecko และ WebKit) ดังนั้นคุณอาจต้องการใช้ชื่ออื่น
"true\0false"[(!x)*5]
:-)
!!x*5
maybe
ถ้าคุณชอบ C ++ ดีกว่า C คุณสามารถลอง:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
หากต้องการพิมพ์ 1 หรือ 0 ตามค่าบูลีนที่ฉันเพิ่งใช้:
printf("%d\n", !!(42));
มีประโยชน์อย่างยิ่งกับ Flags:
#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));
!!
อาจจะได้รับการเพิ่มประสิทธิภาพออกไป
ฉันต้องการคำตอบจากวิธีที่ดีที่สุดในการพิมพ์ผลลัพธ์ของบูลว่า 'เท็จ' หรือ 'จริง' ใน c? , เหมือนกับ
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
ทำจริงๆ หากคุณทำงานในโครงการกับคนอื่น ๆ หรือเพียงแค่ในรหัสโครงการที่คุณต้องการเข้าใจxปีต่อมาการก่อสร้างเช่นนี้จะต้องหลีกเลี่ยง
printf("%s\n","false\0true"+6*(x?1:0));
ซึ่งเป็นเพียง ... 5% อ่านน้อยกว่า
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; }
; เพียงห่อไว้ในฟังก์ชั่นที่มีชื่ออธิบายและไม่ต้องกังวลกับความสามารถในการอ่าน