Vì ANSI C99 có _Bool
hoặc bool
thông qua stdbool.h
. Nhưng cũng có một printf
định dạng định dạng cho bool?
Tôi có nghĩa là một cái gì đó giống như trong mã giả:
bool x = true;
printf("%B\n", x);
sẽ in:
true
Vì ANSI C99 có _Bool
hoặc bool
thông qua stdbool.h
. Nhưng cũng có một printf
định dạng định dạng cho bool?
Tôi có nghĩa là một cái gì đó giống như trong mã giả:
bool x = true;
printf("%B\n", x);
sẽ in:
true
Câu trả lời:
Không có định dạng định dạng cho bool
các loại. Tuy nhiên, vì bất kỳ loại tích phân nào ngắn hơn int
được quảng cáo int
khi được truyền cho printf()
các đối số biến đổi, bạn có thể sử dụng %d
:
bool x = true;
printf("%d\n", x); // prints 1
Nhưng tại sao không:
printf(x ? "true" : "false");
hoặc tốt hơn:
printf("%s", x ? "true" : "false");
hoặc, thậm chí tốt hơn:
fputs(x ? "true" : "false", stdout);
thay thế?
printf("%s", x ? "true" : "false");
sẽ khắc phục vấn đề.
printf("%s", x ? "true" : "false");
là tốt hơn mà printf(x ? "true" : "false");
- bạn đang ở trong tổng số kiểm soát của chuỗi định dạng ở đây do đó không nguy hiểm mà nó sẽ nhận được một cái gì đó như "%d"
đó sẽ gây ra vấn đề. Mặt fputs
khác, là một lựa chọn tốt hơn.
fputs
"thậm chí tốt hơn"? Tôi luôn tìm cách cải thiện C. Trong những trường hợp nào tôi nên sử dụng fputs
thay vì printf
?
Không có định dạng định dạng cho bool. Bạn có thể in nó bằng cách sử dụng một số chỉ định hiện có để in các loại tích phân hoặc làm một cái gì đó lạ mắt hơn:
printf("%s", x?"true":"false");
bool
loại trong C, chỉ cần không có trong phiên bản C89 - đó là một phần của ngôn ngữ đặc tả C99. Có một từ khóa mới _Bool
và nếu bạn bao gồm <stdbool.h>
, thì đó bool
là một từ đồng nghĩa với _Bool
.
ANSI C99 / C11 không bao gồm một công cụ xác định chuyển đổi printf bổ sung cho bool
.
Nhưng thư viện GNU C cung cấp API để thêm các chỉ định tùy chỉnh .
Một ví dụ:
#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;
}
Vì nó là một phần mở rộng glibc, GCC cảnh báo về trình xác định tùy chỉnh đó:
$ gcc -Wall -g main.c -o chính main.c: Trong chức năng 'chính': main.c: 34: 3: cảnh báo: ký tự loại chuyển đổi không xác định 'B' ở định dạng [-Wformat =] r = printf ("Kết quả là:% B \ n", b); ^ main.c: 34: 3: cảnh báo: quá nhiều đối số cho định dạng [-Wformat-Extra-args]
Đầu ra:
$ ./ chính Kết quả là: sai (viết 21 ký tự) $ ./ chính là 1 Kết quả là: đúng (viết 20 ký tự)
Theo truyền thống của itoa()
:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
btoa
là "chuỗi nhị phân thành chuỗi 64 cơ sở" trong JavaScript không chuẩn (Gecko và WebKit), vì vậy bạn có thể muốn sử dụng một tên khác.
"true\0false"[(!x)*5]
:-)
!!x*5
.
Nếu bạn thích C ++ tốt hơn C, bạn có thể thử điều này:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
Tôi thích một câu trả lời từ Cách tốt nhất để in kết quả của một bool là 'false' hoặc 'true' trong c? , giống như
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
thực sự đã làm. Nếu bạn làm việc trong một dự án với những người khác, hoặc chỉ trong một dự án với một cơ sở mã bạn muốn hiểu x năm sau, thì những công trình như thế này là điều nên tránh.
printf("%s\n","false\0true"+6*(x?1:0));
chỉ ... 5% ít đọc hơn.
static inline char const *bool2str(_Bool b) { return "false\0true"+6*x; } int main(void) { printf("%s != %s", bool2str(false), bool2str(true)); return 0; }
Tương tự như với static inline char decimal2char(int d) { assert(d >= 0 && d <= 9); return '0' + d; }
; chỉ cần bọc nó trong một chức năng được mô tả và không lo lắng về tính dễ đọc của nó.