使用C预处理器将int连接到字符串


90

我试图弄清楚如何使用C预处理器将#define'd int串联为#define'd字符串。我的编译器是CentOS 5上的GCC 4.1。该解决方案也应适用于MinGW。

我想在字符串上附加一个版本号,但是唯一可以使它起作用的方法是将版本号的副本定义为字符串。

我能找到的最接近的东西是引用宏参数的方法,但不适用于#defines

这是行不通的。

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" #MAJOR_VER #MINOR_VER

它不没有工作,#小号或者是因为值为数字,它会扩大到"/home/user/.myapp" 2 6,这是无效的Ç

确实可以,但是我不喜欢定义版本的副本,因为我确实也需要它们作为数字。

#define MAJOR_VER 2
#define MINOR_VER 6
#define MAJOR_VER_STR "2"
#define MINOR_VER_STR "6"
#define MY_FILE "/home/user/.myapp" MAJOR_VER_STRING MINOR_VER_STRING

Answers:


171

古典C预处理器问题....

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER)

额外的间接级别将允许预处理器在将宏转换为字符串之前对其进行扩展。


3
在这种情况下,STR()将给出一个窄字符串。是否可以将其转换为宽字符串?
gkns

4
我无法说出我搜索过多少次并从这个确切的答案中复制了
该词

第一个“ STR_HELPER”是必需的,因为“#”仅适用于宏参数。我花了一段时间去弄清楚..
clarkttfu

@clarkttfu,有点-是的,#仅适用于宏参数。但是,STR_HELPER需要使用该宏以避免将宏MAJOR_VER转换为字符串"MAJOR_VAR",而我们希望将结果转换为字符串"2"
Lindydancer

13

一种有效的方法是将MY_FILE编写为参数宏:

#define MY_FILE(x,y) "/home..." #x #y

编辑:如“ Lindydancer”所述,此解决方案不会扩展参数中的宏。一个更通用的解决方案是:

#define MY_FILE_(x,y) "/home..." #x #y
#define MY_FILE(x,y) MY_FILE_(x,y)

1
以我的诚实观点,这是最好的答案,并且比其他建议要简单得多。我很惊讶它没有得到更好的评价!
osirisgothra

5
不幸的是,这是一个干净的解决方案,它行不通。如果传递给的参数MY_FILE是宏,请说AB,该宏将扩展为"/home..." "A" "B"
Lindydancer 2014年

2

您可以使用BOOST_PP_STRINGIZE做到这一点:

#define MAJOR_VER 2
#define MINOR_VER 6
#define MY_FILE "/home/user/.myapp" BOOST_PP_STRINGIZE(MAJOR_VER) BOOST_PP_STRINGIZE(MINOR_VER)

28
让我很傻笑,人们如何向所有事物投掷Boost。
Frerich Raabe

4
@Frerich:让您的论点极端化,人们应该首先在原始机器代码中编写自己的编译器,而不是在所有事情上都投入g ++。优秀的程序员编写代码,优秀的程序员重用。
Maxim Egorushkin 2011年

@jonescb:只需打开boost头并亲自查看。
Maxim Egorushkin 2011年

10
是的,我尝试过。它确实起作用,但是在C程序中使用Boost头对我来说有点奇怪。
jonescb 2011年

1
哦,我不好,没有注意到C标签。
Maxim Egorushkin 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.