自从ANSI C99之后,通过`stdbool.h`头文件可以使用`_Bool`或`bool`类型。但是是否也有针对布尔值的`printf`格式说明符呢?
我的意思是类似于下面这条伪代码:
我的意思是类似于下面这条伪代码:
bool x = true;
printf("%B\n", x);
这将打印出:
true
bool x = true;
printf("%B\n", x);
这将打印出:
true
对于 bool
类型,没有格式说明符。但是,由于任何比 int
更短的整数类型在传递给 printf()
的可变参数时都会被提升为 int
,因此您可以使用 %d
:
bool x = true;
printf("%d\n", x); // prints 1
但为什么不呢:
printf("Your boolean variable is: %s", x ? "true" : "false");
改用什么?
printf("%s", x ? "true" : "false");
会解决这个问题。 - R.. GitHub STOP HELPING ICEprintf("%s", x ? "true" : "false");
不比 printf(x ? "true" : "false");
更好 - 在这里你完全控制格式字符串,所以没有任何危险会出现像 "%d"
这样会导致问题的情况。另一方面,使用 fputs
是更好的选择。 - paxdiablochar *
传递给printf()
被视为不良实践,因为这实际上应该是一个格式字符串。未转义的百分号可能会导致程序崩溃(更多信息请参见此处)。 因此,printf("%s",...)
更安全。 如果您一开始没有进行任何实际格式化,那么printf
函数族就过度了,使用puts()
(或者如果需要打印到stderr
,则使用fputs()
)更加高效/简洁。 - sevkofputs
更好?我一直在寻找提高C语言的方法。在什么情况下,我应该使用fputs
而不是printf
? - Arc676没有适用于bool
的格式说明符。您可以使用一些现有的打印整数类型的说明符来打印它,或者进行更花哨的处理:
printf("%s", x?"true":"false");
bool
类型,但是在C89版规范中没有 -- 它是C99语言规范的一部分。现在有一个新的关键字_Bool
,如果你包含了<stdbool.h>
头文件,那么bool
就是_Bool
的一个同义词。 - Adam RosenfieldANSI C99/C11没有为bool
类型提供额外的printf转换说明符。
一个例子:
#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: In function ‘main’: main.c:34:3: warning: unknown conversion type character ‘B’ in format [-Wformat=] r = printf("The result is: %B\n", b); ^ main.c:34:3: warning: too many arguments for format [-Wformat-extra-args]
输出:
$ ./main 结果为:false (共写入21个字符) $ ./main 1 结果为:true (共写入20个字符)
遵循itoa()
的传统:
#define btoa(x) ((x)?"true":"false")
bool x = true;
printf("%s\n", btoa(x));
"true\0false"[(!x)*5]
:-) (注:此代码片段的作用是根据变量x的真假返回字符串"true"或"false") - paxdiablo!!x*5
。 - jxh如果我只想根据布尔值打印1或0:
printf("%d\n", !!(42));
特别适用于标志:
#define MY_FLAG (1 << 4)
int flags = MY_FLAG;
printf("%d\n", !!(flags & MY_FLAG));
!!
可能会被优化掉。 - interestedparty333!!(flags&MY_FLAG)
可以被替换为(flags&MY_FLAG)
,但是非损坏的编译器除非能够证明操作数不能有任何值而不是0或1,否则无法优化掉!!
。 - supercat如果您比较喜欢C++而不是C语言,您可以尝试以下方法:
#include <ios>
#include <iostream>
bool b = IsSomethingTrue();
std::cout << std::boolalpha << b;
我更喜欢从如何在C语言中以“false”或“true”的形式打印布尔结果的最佳方法中得到答案,就像这样
printf("%s\n", "false\0true"+6*x);
"false\0true"+6*x
实际上是什么意思。如果你在与其他人合作的项目中工作,或者只是在一个你想要在_x_年后理解代码库的项目中工作,应该避免使用这样的结构。 - HelloGoodbyeprintf("%s\n","false\0true"+6*(x?1:0));
,这只会少了5%的可读性。 - Alex Shroyer