如何在C宏中将变量字符串与文字字符串连接起来?

3

我正在创建一个宏,它接受两个字符串:变量字符串和字面字符串。我怎样将它们组合成一个接受单一变量的函数?

我知道我们可以在宏中组合2个字面字符串。

#define LOGPRINT(x,y) func(x y)
#define LOGPRINTSINGLE(x) func(x)

func(char *fmt)
{
   printf(fmt);
}

下面的代码是有效的:

char * test = "hey "; 

LOGPRINT("hello ", "world!");
LOGPRINTSINGLE(hey);

但是下面的代码无法运行。
LOGPRINT(test, "world!");

我如何在宏中将可变字符串测试与文字字符串“world”组合?
期望的结果是将“hey world”传递给func()。
**编辑/注:规则是我只允许在此代码中更改,而不更改调用者和func()。

7
简短的回答是:你不能。预处理器在“正式”编译之前作为一个单独的步骤运行。因此,预处理器不知道任何关于变量的信息,更不用说变量的可能内容了,因为这些只有在运行时才知道,可能是在编译之后很长一段时间。 - Some programmer dude
如果你真的使用C++(如标签所示),那么你可以使用#define LOGPRINT(x,y) func((std::string(x) + std::string(y)).c_str()) - sklott
请选择一种编程语言。 - Antti Haapala -- Слава Україні
使用“真实”函数而不是宏。它接受两个const char *参数;你的所有问题都会消失。即使是代码膨胀问题也一样。 - Jonathan Leffler
XY 问题。你不需要字符串拼接,而需要一个能正常工作的日志宏。具体来说,就像 printf 函数一样。 - n. m.
请不要在已经有某种语言回答的情况下删除该语言标签。在删除标签之前,这个问题曾经有过一个 C++ 的回答。请不要这样做 - 一旦有答案发布,就为时已晚了。 - Lundin
2个回答

2
也许不是世界上最美观或最安全的宏,但它有效 :-)
最初的回答
#include <stdio.h>
#include <string.h>

#define LOGPRINT(x,y)                       \
{                                           \
char dest[strlen(x) + strlen(y) + 1];       \
memcpy(dest, x, strlen(x));                 \
memcpy(dest + strlen(x), y, strlen(y));     \
dest[strlen(x) + strlen(y)] = 0;            \
func(dest);                                 \
}
#define LOGPRINTSINGLE(x) func(x)

void func(char *fmt)
{
   printf(fmt);
}


int main()
{
    char * test = "hey "; 

    LOGPRINT("hello ", "world!");
    printf("\n");
    LOGPRINTSINGLE(test);
    printf("\n");
    LOGPRINT(test, "world!");

    return 0;
}

输出:

hello world!
hey
hey world!

6
计算机科学中只有两个困难问题:取名字、缓存失效和 off-by-one 错误。 - Antti Haapala -- Слава Україні
让Antti Haapala想要说的更清楚:dest的大小少了一个。 - Gerhardh
你不需要使用 strncpy - 因为你已经知道长度,只需使用不扫描终止0的 memcpy 即可。 - Antti Haapala -- Слава Україні
是的,我也注意到了,但我并不在意,因为使用strncpy而不是strcpy会导致相同的行为。我不知道strncpy的内部情况,也许在大多数架构上它比memcpy慢一点。为了美观起见,我会将其更改为memcpy :-) - flott
@AizatKhir 我试图使用strncat,但最终让我头疼 你不是唯一一个... - Andrew Henle
显示剩余2条评论

1
使用C++字符串非常简单,如果包含“string”STL。
#define LOGPRINT(x,y) func(x y)更改为#define LOGPRINT(x,y) func((std::string(x) + std::string(y)).data())#define LOGPRINT(x,y) func(std::string(x).append(y).data())

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