ChatGPT解决这个技术问题 Extra ChatGPT

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

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

我想将版本号附加到字符串上,但我可以让它工作的唯一方法是将版本号定义为字符串的副本。

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

这是行不通的。

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

如果没有 #,它也不起作用,因为值是数字,它会扩展为 "/home/user/.myapp" 2 6,这是无效的 C

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

#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

L
Lindydancer

经典的 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)

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


在这种情况下,STR() 将给出一个 Narrow 字符串。是否有将其转换为宽字符串的变体?
我不能说我用谷歌搜索了多少次并从这个确切的答案中复制了它,但它会是两位数
第一个“STR_HELPER”是必需的,因为“#”仅适用于宏参数。我花了一些时间才弄清楚..
@clarkttfu,有点——是的,# 仅适用于宏参数。但是,需要使用 STR_HELPER 宏来避免将宏 MAJOR_VER 变成字符串 "MAJOR_VAR",而我们希望结果是 "2"
我的大脑很痛,这不能用一个宏来完成......就像很多其他人一样,使用了几十次
G
Giuseppe Guerrini

一种可行的方法是将 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)

老实说,这是最好的答案,并且比其他建议简单得多。我很惊讶它没有得到更好的评价!
这是一个干净的解决方案,不幸的是,它不起作用。如果传递给 MY_FILE 的参数是宏,例如 AB,则此宏将扩展为 "/home..." "A" "B"
M
Maxim Egorushkin

您可以使用 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)

让我傻笑人们如何在任何事情上都使用 Boost。
@Frerich:把你的论点极端化,人们应该首先用原始机器代码编写自己的编译器,而不是把 g++ 扔在所有东西上......没有必要重新发明轮子。优秀的程序员编写代码,优秀的程序员重用。
@jonescb:只需打开 the boost header 并亲自查看。
是的,我试过了。它确实有效,但在 C 程序中使用 Boost 标头对我来说似乎有点奇怪。
哦,我的错,没有注意到 C 标签。