如何创建一个C宏来附加/ n到每个printf

时间:2015-11-05 06:41:36

标签: c visual-studio macros printf

MY_PRINT是整个代码中的一个宏,它只是printf。 我想暂时修改它以在每次printf之后附加\ n。

然而,当我这样做时:

#define SENS_PRINT(x)        printf(x);   printf("\n")
MY_PRINT( "\n   #%d:  %c    ", ++command_line_number, sensor_operation_code );

...输出为垃圾:#3405240: <alpha symbol>

这打印好,但最后没有\ n:

#define SENS_PRINT   printf

3 个答案:

答案 0 :(得分:4)

您希望您的宏能够采用各种参数,就像真正的printf一样。您可以使用可变参数宏来执行此操作。

当宏是条件代码块中唯一的表达式时,还存在两个单独的表达式不被解释为宏所暗示的危险。想想如果你说if (flag) SENS_PRINT(...);宏会做什么。防止这种情况的一种方法是将宏包装在do { ... } while(0)块中。

printf添加换行符的可变参数宏可能如下所示:

#define PRINTFLN(...) do { printf(__VA_ARGS__); puts(""); } while (0)

您可以像printf

一样使用它
PRINTFLN("Hello %s!", "cruel world");
if (flag) PRINTFLN("%d + %d == %d", x, y, sum);

答案 1 :(得分:2)

C语言允许您连接由空格分隔的字符串文字。如果您对MY_PRINT的所有调用都使用字符串文字作为其格式化参数,则可以定义一个可变宏,它将"\n"直接附加到您的格式字符串,然后应用其余的参数。< / p>

像这样定义你的宏

#define MY_PRINT(format, ...) printf(format "\n", __VA_ARGS__)

您将能够直接在格式化参数中添加换行符。

使用此方法只会执行一个函数调用,但使用除字符串文字以外的任何其他格式调用将导致编译错误。

答案 2 :(得分:1)

函数行宏的问题在于,预处理将所有逗号分隔的参数视为宏的参数,而不是单个参数。所以你的编译器应该抱怨你传递给宏的许多参数。

一个简单的解决方案是将宏参数括在括号中:

MY_PRINT( ( "\n   #%d:  %c    ", ++command_line_number, sensor_operation_code ) );
//        ^                                                                   ^
//        |                                                                   |
// Note extra parentheses here...                                      and here

另一种解决方案是使用variadic macros

在某种程度上相关的说明中,您所显示的宏不能在构造中使用,例如。

if (some_condition)
    MY_PRINT(...);

将替换为

if (some_condition)
    printf(...);
printf(...);

如果宏中有多个语句,则需要将其括在一个块中,例如

#define MY_PRINTF(...) \
    do {               \
        statement1;    \
        statement2;    \
        .              \
        .              \
        .              \
        statementN;    \
    } while (0)