在C#中连接字符串,使用#include文件名。

15

当在C语言中使用#include引入文件时,能否从另一个宏中连接字符串。例如,

我有以下代码:

#define AA 10 
#define BB 20

这些是随程序运行而变化的参数。

文件包括:

#include "file_10_20" // this changes correspondingly i.e. file_AA_BB

有没有可能实现类似于#include "file_AA_BB"这样的东西?我搜索了一下发现双井号操作符可以连接字符串,但是没找到具体实现的方法。

非常感谢任何帮助。


尝试使用 #include #(file_##AA##_##BB) - asaelr
2个回答

22

一开始我以为"这很简单",但尝试了几次才明白:

#define AA 10 
#define BB 20

#define stringify(x) #x
#define FILE2(a, b) stringify(file_ ## a ## _ ## b)
#define FILE(a, b) FILE2(a, b)

#include FILE(AA, BB)

根据要求,我将尝试解释。 FILE(AA, BB) 展开为 FILE2(AA, BB),但是在展开 FILE2 之前会先展开AABB,因此下一次展开是 FILE2(10, 20),它展开为 stringify(file_10_20),成为字符串。

如果跳过 FILE2,则最终结果将是 stringify(file_AA_BB),这不起作用。实际上,C标准花费了几页来定义宏展开的方式。根据我的经验,最好的思路是 "如果展开不够,请添加另一层 define"。

只有字符串化操作将不起作用,因为#在AA被替换为10之前就被应用了。实际上,这通常是您想要的,例如:

#define debugint(x) warnx(#x " = %d", x)
debugint(AA);

将会打印

AA = 10

如果你能解释一下为什么需要FILE宏,我会点赞的 ;-)。我已经看到了许多这样的结构,但从未理解为什么只有2个宏不起作用,甚至为什么asael的答案也不起作用。我非常想知道预处理器在你的示例中是如何工作的。有人能解释一下吗? - Artur
2
不要忘记使用 #undef FILE,因为它会与 <stdio.h> 中的某些内容冲突。 - wildplasser
好的,或许不是最佳的宏名称选择。 - Per Johansson
首先,感谢提供的详细信息。我即将尝试这个,但在此之前,我正在努力理解它,而不仅仅是简单地使用它。我不明白为什么需要定义FILE和FILE2。您说仅使用stringify不起作用-我不明白为什么不能这样做。 - anasimtiaz
2
@Per:感谢您的解释。我认为每个对这个问题感兴趣的人都会喜欢阅读http://www.delorie.com/gnu/docs/gcc/cpp_32.html。 - Artur
显示剩余3条评论

6

通常它被这样使用:

#define stringify(x)  #x
#define expand_and_stringify(x) stringify(x)

#define AA 10
#define BB 20

#define TEXT1 "AA = " stringify(AA) " BB = " stringify(BB)
#define TEXT2 "AA = " expand_and_stringify(AA) " BB = " expand_and_stringify(BB)

TEXT1 = "AA = AA BB = BB"
TEXT2 = "AA = 10 BB = 20"

这被称为字符串化。您应该查看这个答案


这不应该适用于include语句吗?请参见https://dev59.com/u3rZa4cB1Zd3GeqPyyMR#20524959和https://dev59.com/mFkT5IYBdhLWcg3wG8D4。 - Antonio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接