如何将字符常量连接成字符串。 C

时间:2014-04-22 07:06:22

标签: c string

如果我在C中定义了一个常量字符,我可以将它合并为一个字符串文字吗?

#ifdef WIN32
#  define SEP '\\'
#  define ALTSEP '/'
#else
#  define SEP '/'
#  define ALTSEP '\\'
#endif

#define SOME_STRING_LITERAL "foo"

/* code snippet */
/* Desired string: "prefix_foo/bar" */
const char *path = "prefix_" SOME_STRING_LITERAL SEP "bar";

当然这会失败,因为SEP没有被定义为字符串文字,但有没有办法使SEP正确连接?或者我需要另一个定义,例如#define SEP_STR "/"

3 个答案:

答案 0 :(得分:2)

我认为你不能用C做到这一点。

核心问题是"符号非常重要,即使在预处理器知道应该将其视为预处理令牌之前,它也会得到解释。

使用#运算符进行字符串化不会有帮助。即使你写了像

这样的宏
#define STRINGINIZE(x) #x
#define CHAR_TO_STR(ch) STRINGINIZE(ch)

然后将其作为

调用
const char *path = "prefix_" SOME_STRING_LITERAL CHAR_TO_STR(SEP) "bar";

它对你没有好处,因为你最终会得到像

这样的字符串
prefix_foo`\`bar

你也做不到这个:

const char *path = "prefix_" SOME_STRING_LITERAL CHAR_TO_STR(SEP)[1] "bar";

因为它与我们在第一时间所拥有的相同,所以它不会被编译。

此外,您无法基于串联预处理器令牌来制定解决方案,因为"是比##更基本的符号。

所以唯一的解决方案似乎是将字符声明为字符串文字。

答案 1 :(得分:0)

您可以使用编译时字符串化运算符#

#define SEP_STR(x) #x
#define SEP_STR_2(x) SEP_STR(x)

const char *path = "prefix_" SOME_STRING_LITERAL SEP_STR_2(SEP) "bar";

或者您可以将SEP定义为"\\"

由于this link

中解释清楚的原因,因此需要双级MACRO扩展

简而言之:

  

如果要对宏参数的扩展结果进行字符串化,则必须使用两级宏。

答案 2 :(得分:0)

不要将SEP定义为字符,而是将其定义为字符串。

#include <stdio.h>
#define SEP "\\"
#define SOME_STRING_LITERAL "foo"
int main() {
    const char * path = "prefix_" SOME_STRING_LITERAL SEP "bar";
    puts(path);
    return 0;
}

输出:prefix_foo\bar