如何为C宏字符串化char缓冲区

时间:2019-01-24 19:18:47

标签: c macros c-preprocessor stringification

我有一个LOG(fmt, ...)宏,在将char buf[]用作fmt时不起作用。

下面的代码是该代码的完整(而非实际)工作示例。在some_function()中,我尝试以两种不同的方式使用LOG(),但只有第一种方法有效。

为解决该问题,我尝试通过以下方式使用#define LOG_STR(x) #x

  1. 通过#define LOG应用于LOG_STR()format,以{em> stringify 在LOG_STR(format)中接收到的内容:和

  2. LOG_STR()直接应用于印刷,例如:LOG(LOG_STR(fmt), 6)

这两种方法都行不通,实际上我从中发现了段错误。

    #include <stdio.h>

    #define LOG(format, ...) do {                             \
                fprintf(stderr, "[LOG] " format " [%s]\n",    \
                        ##__VA_ARGS__, __func__);             \
            } while (0)

    static void some_function()
    {
        // This works
        LOG("This is a number: %d", 5);

        // This does not work
        const char fmt[] = "This is a number: %d";
        LOG(fmt, 6);
    }

    int main(void)
    {
        some_function();
        return 0;
    }

当我编译上面的代码时,出现以下错误:

$ gcc -o log-macro-str log-macro-str.c
log-macro-str.c: In function ‘some_function’:
log-macro-str.c:15:6: error: expected ‘)’ before ‘fmt’
  LOG(fmt, 6);
      ^
log-macro-str.c:4:29: note: in definition of macro ‘LOG’
    fprintf(stderr, "[LOG] " format " [%s]\n",    \
                             ^~~~~~

我想像在LOG()中一样使用两种方式使用some_function(),也可以不使用修饰符,而只是打印一个字符串。我怀疑我可能需要对format部分进行字符串化处理,但是我似乎无法正确执行。

我在做什么错了,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

宏中的字符串化运算符#将预处理器标记转换为字符串文字中的文本。不会将char缓冲区的内容更改为编译时字符串文字。

要使宏正常工作,请使用多个fprintf语句:

#define LOG(format, ...) do {                          \
            fprintf(stderr, "[LOG] ");                 \
            fprintf(stderr, format, __VA_ARGS__);      \
            fprintf(stderr, " [%s]\n", __func__);      \
        } while (0)