【问题标题】:How to make printf() properly print a binary blob from within a macro?如何使 printf() 从宏中正确打印二进制 blob?
【发布时间】:2010-06-24 09:15:48
【问题描述】:

在我的一个项目中(出于技术原因,不得依赖任何外部库或第三方资源)我设置了以下test.h

static int rc = 0;
#define TESTCASE( x ) if ( x ) {} \
                      else \
                      { \
                          rc += 1; \
                          printf( "FAILED: " __FILE__ ", line %d - " #x "\n", __LINE__ ); \
                      }

这在大多数情况下都可以正常工作 - 如果测试用例评估为 true,则不会发生任何事情。如果测试用例评估为假,则打印测试用例,包括文件名和行号。

但是,当测试用例包含字符串文字时,TESTCASE 宏中的printf() 坚持将字符串文字解释为格式字符串的一部分(这对某些测试用例来说是致命的)。

现在我正在考虑各种方法来让printf() 逐字打印x(测试用例)中的任何内容,但我发现是空的。最接近的方法是使用%c 打印固定数量的字符,并将文本大小写(#x)作为参数传递给printf() - 但我不知道如何确定#x 的大小,特别是如果它包含零字节(这排除了strlen() 的任何使用)。

困惑,不知所措。帮忙?

【问题讨论】:

    标签: c macros printf


    【解决方案1】:

    使用%s 作为格式然后将字符串化的测试用例作为参数传递怎么样,就像你对行号所做的那样?

    printf( "FAILED: %s, line %d - %s\n", __FILE__, __LINE__, #x );
    

    # 将参数转换为正确的双引号分隔字符串,因此没有什么能阻止您将此字符串作为参数传递给 printf...

    (你永远不应该使用任何没有硬编码的值作为 printf 的格式字符串:这在大多数情况下都会引发地狱)

    【讨论】:

    • 第一个方法很好,但是如果 #x 中的字符串文字包含零字节怎么办?
    • 我认为这是不可能的:零字节没有表示,它在 C 源文件中无效,因此不能出现在您的测试用例中。 (或者您问题中TEST_CASE 宏的定义是错误的)请记住# 预处理器运算符是一个字符串化器,它将abc 转换为"abc" 的宏参数中的字面意思。
    • 在这里,当我意识到 '\0' 是一个零字节,而不是事物本身。啊啊啊……我的半个脑袋一定是睡着了。当然,你是绝对正确的。
    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2020-12-02
    • 2016-10-20
    • 1970-01-01
    • 2020-11-09
    相关资源
    最近更新 更多