c预处理器字符串连接

时间:2012-11-22 05:13:27

标签: c c-preprocessor

如何组合预定义的C值以生成字符串。

#define APP_NUMBER 22
#define ICON_FILE  "../icons/"##APP_NUMBER##".ico"

这样在我的.rc文件中我可以执行以下操作

 1000 ICON  ICON_FILE
而不是      1000 ICON“../ icons / 22.ico”

  
    

它没有用

  
  #define MY_ICON_FILE 25
  #define STR(x) #x
  #define ICON_FILE_NUM(x) "../icons/" STR(x) ".ico"
  1000 ICON  ICON_FILE_NUM(MY_ICON_FILE)

编译错误

  can't open icon file `../icons/': Permission denied

  nothing was appended to "../icons/"
我刚刚得到的最接近的是:

  #define MY_ICON_FILE 25
  #define STR(x) #x
  #define ICON_FILE_NUM(x) "../icons/"STR(x)".ico" /// took out spaces
  1000 ICON  ICON_FILE_NUM(MY_ICON_FILE)

(取出STR(x)周围的空格)

并得到此编译器错误

 can't open icon file `../icons/"25".ico': Invalid argument

4 个答案:

答案 0 :(得分:3)

这有效:

#define APP_NUMBER 22
#define STR(x) #x
#define ICON_FILE_NAME(num)  "../icons/" STR(num) ".ico"
#define ICON_FILE ICON_FILE_NAME(APP_NUMBER)

#include <stdio.h>
int main(void) {
    printf("ICON_FILE = \"%s\"\n", ICON_FILE);
    return 0;
}

输出结果为:

ICON_FILE = "../icons/22.ico"

ICON_FILE宏扩展为"../icons/" "22" ".ico",这是C的有效语法(相邻的字符串文字连接在一起),但可能不适用于.rc文件,这解释了“可以你打开的“打开图标文件”消息。

看起来您正在尝试使用令牌粘贴来生成字符串文字。问题在于,包含无法匹配的"字符的部分字符串文字不能是有效的预处理标记。例如,您不能将单个"作为参数传递给宏。

考虑编写一个程序(脚本,无论如何),为您生成适当的#define指令。

答案 1 :(得分:1)

Windows资源文件不了解大多数元素的C样式文字字符串连接 - 字符串表可能是唯一的例外。

使用预处理器宏时的技巧是不使用字符串作为输入起点,预处理器不知道如何删除引号。

仅连接一次也会有所帮助 - 考虑添加搜索路径"-I../icons/",而不是添加资源名称的路径。

使用windows msvc从boost中取出以下内容,例如使用额外的间接级别,而不是我在大多数地方看到的内容。

#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_OO((a, b))
#    define BOOST_PP_CAT_OO(par) BOOST_PP_CAT_I ## par
#    define BOOST_PP_CAT_I(a, b) a ## b

#    define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text))
#    define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_I arg
#    define BOOST_PP_STRINGIZE_I(text) #text

在示例中,您似乎可以执行 BOOST_PP_CAT(../icons/, BOOST_PP_CAT(num,.ico))

传递给stringize有一个问题,只应用外部CAT(至少在Windows上)。所以 BOOST_PP_STRINGIZE(BOOST_PP_CAT(../icons/, BOOST_PP_CAT(num,.ico)))无效。

添加3个项目的连接

#    define BOOST_PP_CAT2(a, b, c) BOOST_PP_CAT_OO2((a, b, c))
#    define BOOST_PP_CAT_OO2(par) BOOST_PP_CAT_I2 ## par
#    define BOOST_PP_CAT_I2(a, b, c) a ## b ## c

在我的VS2013测试中输入

  • ..正在转换为"...",这使得使用相对路径difficult
  • \需要转发\\才能使用宏args,但正在转换为"\\" - 使用/可以更好地使用路径

使用字符串表比使用图标

更容易看到输出
STRINGTABLE
BEGIN
  123  BOOST_PP_STRINGIZE(BOOST_PP_CAT(APP_NUMBER, .ico))
  124  BOOST_PP_STRINGIZE(BOOST_PP_CAT2(../icons/, APP_NUMBER,.ico)))
END

我还没有解决......被转换为...... 我使用其他搜索路径

进行了以下工作
1000        ICON        BOOST_PP_STRINGIZE(BOOST_PP_CAT(APP_NUMBER, .ico))
1001        ICON        BOOST_PP_STRINGIZE(BOOST_PP_CAT2(icons/, APP_NUMBER, .ico))

答案 2 :(得分:-1)

我会诚实地避免使用预处理器。调试预处理器错误是一件痛苦的事情,我发现使用多层预处理器替换和连接的情况,在尝试查找问题时会导致灾难。我的2美分。

答案 3 :(得分:-1)

我认为你不能用C预处理器做到这一点。但是,您可以使用m4预处理器。

linux_prompt> cat icon.m4
define(APP_NUMBER, 22)

1000 ICON "../icons/APP_NUMBER.ico"

linux_prompt> m4 icon.m4

1000 ICON "../icons/22.icon"

您必须确保文件的其余部分正确扩展。请“男人m4”获取更多信息。