如何对包含逗号的字符串进行字符串化?

时间:2013-12-04 19:57:24

标签: c++ c-preprocessor stringification variadic-macros

我想在编译命令中传递一个版本字符串:

$ g++ -Wall -D VERSION="2013-12-03 02:15:21, commit cb060df" -o main main.cpp

在我的代码中,我有以下内容:

#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(x)
#define VERSION_STR STRINGIFY(VERSION)

这不起作用,因为VERSION宏中有一个逗号,所以看起来我将两个参数传递给TOSTR()(显然,只有VERSION宏在作为一个唯一参数传递给STRINGIFY()之后得到扩展。

我在here中找到的以下方法也不起作用:

#define CONCAT(...) __VA_ARGS__
#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(CONCAT(x))
#define VERSION_STR STRINGIFY(VERSION)

因为这似乎与

相同
#define VERSIONSTR "CONCAT(2013-12-03 02:15:21, commit cb060df)"

即,宏CONCAT()不会扩展。

注意1:我宁愿不在命令行中传递 C 字符串,因为版本字符串实际上是动态生成的,并且可能包含一些引号。这意味着只编写g++ -D VERSION=\""$(GENERATED_STRING)"\"而不是对传递的参数进行字符串化将无效。

注意2:如果有人在没有任何预处理器宏的情况下找到了这样做的话,我会非常高兴。

2 个答案:

答案 0 :(得分:7)

您可以编写TOSTR_宏来获取变量参数:

#define TOSTR_(x...) #x
#define STRINGIFY(x) TOSTR_(x)
#define VERSION_STR STRINGIFY(VERSION)

此代码已经过测试,适用于Apple LLVM 5.0版。

答案 1 :(得分:0)

__ VA_ARGS__必须在每次通话中:

#define _STRINGIZE(...) #__VA_ARGS__
#define STRINGIZE(...) _STRINGIZE(__VA_ARGS__)