我可以有这样的东西吗?
#include <stdio.h>
#define CAT2(a1, a2) #a1 ## ";" ## #a2
int main(void)
{
const char *ch1 = "1";
const char *ch2 = "2";
puts(CAT2(ch1, ch2));
}
输出:
1;2
但目前我有
ch1;ch2
用字符串文字# operator
替换给他的参数。
代表着 :
#define TO_STR(arg) #arg
const char* ch1 = "1";
TO_STR(ch1) // <- Will give "ch1"
从标准:
16.3.2 # 运算符 [cpp.stringize]
字符串文字是没有前缀的字符串文字。如果在替换列表中,一个参数前面紧跟一个
#
预处理标记,则两者都被一个字符串文字预处理标记替换,该预处理标记包含对应参数的预处理标记序列的拼写。
因此,在您的情况下,您尝试连接(与## operator
):
"ch1" ## ";" ## "ch2"
这解释了你得到的结果。
由于 MACRO 是在预处理时评估的,因此您无法以您想要的方式连接变量。
如果你在 C 中,你应该使用strcat
例如。
如果你在 C++ 中,为什么不使用std::string
或者在 C++11 中你可以使用snprintf
.
不幸的是,由于宏是在编译时计算的,所以您不能使用变量的值,这是宏的主要限制因素。即他们不能评估运行时值。
您不能以您想要的方式使用宏进行字符串连接。
使用 snprintf 来准备您的字符串:
char tmp[20];
snprintf(tmp, sizeof(tmp), "%s;%s", ch1, ch2);
宏在编译时被扩展,在实际编译之前,它无法知道运行时的值。
您可以将上面的代码包装到将返回 tmp 的函数中(只是不要忘记使 tmp 静态变量以防止泄漏)。
char* cat2(char *ch1, char* ch2)
{
static char tmp[50];
snprintf(tmp, sizeof(tmp), "%s;%s", ch1, ch2);
return tmp;
}
// inside main
puts(cat2(ch1, ch2));