在C语言中编写宏以调用返回整数的函数并返回一个字符串

5
我有一个返回整数值的函数。现在我想写一个宏来调用这个函数,获取返回值并在其前面添加一个字符串,然后返回结果字符串。
我尝试过以下代码:
#define TEST(x)        is_enabled(x)

我在主函数中调用这个宏:

int ret = 0;
ret = TEST(2);
printf("PORT-%d\n", ret);

这个功能非常完美。不过,我希望宏可以返回字符串PORT-x的形式,其中x是调用函数的返回值。我该怎么做?
编辑: 我也尝试将其写成多行形式:
#define TEST(x)\
{\
    is_enabled(x);\
}

在主函数中调用它的方式如下:

printf("PORT-%d\n", TEST(2));

但是这会引起编译时错误:

error: expected expression before â{â token

可以通过编写一个“调用” sprintf 的宏来完成,但您需要分配一个缓冲区并将其传递给该宏。问题是,为什么您要这样做?因为感觉您正在以错误的方式解决某些问题。 - barak manos
为什么不能使用 strcat?为什么需要一个宏? - Gopi
你一定要为此编写一个函数... - Antzi
@Gopi,我不想改变基础函数来返回字符串,所以我想到了使用宏修改该函数的输出的想法。这很难吗? - iqstatic
2个回答

5
请使用函数而不是宏。在这里使用宏没有好的理由。
您可以通过使用`sprintf(3)`以及`malloc`或缓冲区来解决此问题。有关详细信息,请参见创建C格式化字符串(而不是打印它们)或手册页面。
关于您的编辑:您不需要在宏中使用大括号{},因为它们会导致错误,因为预处理将其转换为类似于的内容
printf("format%d", {
  is_enabled(x);
}); 

为了更好地理解宏,可以使用带有-E标志的gcc或clang运行代码,或尝试阅读本文:http://en.wikipedia.org/wiki/C_preprocessor

最后,我将其实现为一个函数而不是编写宏。 - iqstatic

2

由于需要确保有足够的存储空间来存储字符串,因此这有点麻烦。老实说,现在宏可能仅用于条件编译。

常量最好使用枚举类型来定义,而宏函数通常最好作为内联函数(要知道inline只是对编译器的建议,而不是强制要求)。

如果您坚持使用宏,则可以使用静态存储来处理,但如果使用线程,则会出现问题,并且返回的字符串可能会被延迟/多次使用。

您还可以动态分配字符串,但然后必须在完成后释放它,并处理内存不足的情况。

也许最简单的方法是要求宏用户提供自己的存储空间,类似于:

#include <stdio.h>

#define TEST2_STR(b,p) (sprintf(b,"PORT-%d",p),b)

int main (void) {
    char buff[20];
    puts (TEST2_STR(buff, 42));

    return 0;
}

这将输出:

PORT-42

如果宏看起来有点困惑,那是因为它使用了逗号运算符,其中表达式 (a, b) 会同时计算 ab,并将结果返回为 b
在这种情况下,它会评估 sprintf(填充缓冲区),然后“返回”缓冲区。即使你认为自己以前从未见过这种写法,你可能也是错的。
for (i = 0, j = 9; i < 10; i++, j--)
    xyzzy[i] = plugh[j];

尽管大多数人认为这是 for 的一个特性,实际上它是一种不同的结构,可以在许多不同的地方使用:

int i, j, k;
i = 7, j = 4, k = 42;

while (puts("Hello, world"),sleep(1),1);

(and so on)。

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