C中将布尔值打印为'false'或'true'的最佳方法是什么?

21
我必须编写一个程序,其中main调用其他函数来测试一系列数字,判断是否有数字小于某个数,如果所有系列的数字都在两个限制之间,并且是否有负数。
我的代码返回值为1表示真和0表示假,但是任务要求将它们打印为'真'或'假'。我不确定如何从printf中将布尔答案打印为字符串。我在我的at_least.c文件和main.c文件中使用了if (atl == false) printf("false");,但它只返回一长串的true或false(例如:truetruetrue....)。
我不确定这是否是正确的编码方式,我是否把它放错位置,或者是否需要使用其他代码。
#include "my.h"

int main (void)
{
    int     x;
    int     count    = 0;
    int     sum      = 0;
    double  average  = 0.0;
    int     largest  = INT_MIN;
    int     smallest = INT_MAX;
    bool    atlst    = false;
    bool    bet      = true;
    bool    neg      = false;
    int     end;

    while ((end = scanf("%d",&x)) != EOF)
    {
        sumall(x, &sum);                        // Calling function sumall
        count++;
        larger_smaller(x, &largest, &smallest); // Calling function larger_smaller
        if (atlst == false)
           at_least(x, &atlst);                 // Calling function at_least if x < 50
        if (bet == true)
           between(x, &bet);                    // Calling function between if x is between 30 and 40 (inclusive)
        if (neg == false)
           negative(x, &neg);                   // Calling function negative if x < 0
    }

    average = (double) sum / count;
    print(count, sum, average, largest, smallest, atlst, bet, neg);
    return;
 }

一组数字的结果:

The number of integers is:           15
The sum is               :         3844
The average is           :       256.27
The largest is           :          987
The smallest is          :          -28
At least one is <  50    :            1     // This needs to be true
All between  30 and  40  :            0     // This needs to be false
At least one is negative :            1     // This needs to be true

这是关于C语言的,我似乎找不到太多相关的信息。

附录:

以下内容是从下面一个答案中复制过来的。

这对于at_leastnegative函数是有效的,但对于between函数则无效。我已经尝试过

void between(int x, bool* bet)
{
    if (x >= LOWER && x <= UPPER)
        *bet = false;
    return;
}

我的代码。哪里出错了?


2
只是一点小提示,在布尔表达式中,x == true 是多余的;你可以直接写 x。同样地,x == false 可以简写为 !x - Jon Purdy
可能是What is the printf format specifier for bool?的重复。 - Brad Solomon
5个回答

50

替代的无分支版本:

"false\0true"+6*x

19
一个带有自解释性名称(例如bool2str)的内联函数或宏可以解决这个问题。 - R.. GitHub STOP HELPING ICE
5
这实际上是做什么的?你能为那些在学习C语言时偶然浏览到这个答案的人提供一些细节吗? - William Everett
5
@ArchaeaSoftware:我不知道你所说的“不兼容Unicode”的意思。字符串的唯一可能的Unicode表示是UTF-8。但即使你有一个wchar_t字符串(带有L前缀),代码仍然有效,因为指针加法是基于数组元素而不是字节的。你的评论表明你对C语言的理解不足。 - R.. GitHub STOP HELPING ICE
4
表达式"false\0true"实际上会被解释为指向该程序内存中这个特定字符串的const char 。当x为1(true)时,“+6x”将6添加到指针上,而当x为0(false)时则不加。如果向指针添加了0,则printf将从“f”处开始读取字符串,并在遇到空结束符“\0”时停止读取。相反,如果添加了6,则printf将从“t”处开始读取字符串,并在字符串自然终止时停止读取。但是,如果x不是0或1,此构造将失败,因此如果无法保证x的值,则需要@R的修正。 - HelloGoodbye
5
可以进行优化以避免使用乘法,而是使用移位操作(在大多数CPU/平台上仍然是一种相关的优化技巧):"false\0\0\0true"+8*x - jstine
显示剩余7条评论

28
你可以使用C语言的条件(或三元)运算符:
  (a > b) ? "True" : "False";

或者在你的情况下:
  x ? "True" : "False";

18

x ? "true" : "false"

上述表达式返回一个char *类型的结果,因此您可以按以下方式使用:

puts(x ? "true" : "false"); 或者 printf(" ... %s ... ", x ? "true" : "false");

你可能想要为此创建一个宏。


3
技术上来说,它是一个 const char* 而不是一个 char*(尽管从前者到后者有一种已经弃用的转换方式),但这在这里并不重要。 - Adam Rosenfield
2
当内联函数可以完成工作时,创建宏没有意义。 - kevin cline
3
不,它是“char *”。这是C语言,不是C++。 - R.. GitHub STOP HELPING ICE

4
使用这个。
#include <stdio.h>

#define BOOL_FMT(bool_expr) "%s=%s\n", #bool_expr, (bool_expr) ? "true" : "false"

int main(int iArgC, char ** ppszArgV)
{
    int x = 0;
    printf(BOOL_FMT(x));

    int y = 1;
    printf(BOOL_FMT(y));

    return 0;
}

这将打印出以下内容:
x=false
y=true

使用这个与类型bool一起,但是int应该以相同的方式工作。

你可能想将 printf 调用添加到宏中。虽然由于逗号运算符的工作方式,您可以使用额外的括号来执行类似 puts((BOOL_FMT(1))) 的操作以打印 true - Oscar Korz

2

我有三个数组:

strbool.c:

#include "strbool.h"

const char alx_strbool[2][6]    = {"false", "true"};
const char alx_strBool[2][6]    = {"False", "True"};
const char alx_strBOOL[2][6]    = {"FALSE", "TRUE"};

strbool.h:

#pragma once

/* rename without alx_ prefix */
#if defined(ALX_NO_PREFIX)
#define strbool     alx_strbool
#define strBool     alx_strBool
#define strBOOL     alx_strBOOL
#endif

extern  const char alx_strbool[2][6];
extern  const char alx_strBool[2][6];
extern  const char alx_strBOOL[2][6];

免责声明:前缀是必需的,因为以 str 开头的名称是保留的(实际上,只有 strbool),但在它们被 C 或 POSIX 实际使用之前,我将使用简短版本。
使用它们非常简单:
#include <stdio.h>

#define ALX_NO_PREFIX
#include "strbool.h"

int main(void)
{
        int var = 7;

        printf("var is %s\n", strBool[!!var]);

        return 0;
}

var is True

将其转换为bool类型似乎有些不切实际和不实用。也许以这种方式定义strbool会更自然一些?#define strbool(x) alx_strbool[!!(x)] - Vélimir
1
@Sho 是的,那可能是一个选项。如果一个函数似乎更自然地使用,我会编写一个inline函数并接受一个bool参数,而不是一个类似于函数的宏;这将是最可读/直观的事情。无论如何,请记住标识符strbool()可能被标准保留。请注意,我说的是可能保留,而不是保留,因为C2x承认未被标准使用的可能保留标识符尚未被保留。 - alx - recommends codidact

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接