4

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

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

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

 1000 ICON  ICON_FILE

而不是 1000 图标“../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

4 回答 4

4

这有效:

#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考虑编写一个为您生成适当指令的程序(脚本,等等) 。

于 2012-11-22T06:09:23.947 回答
1

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

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

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

从 boost 中提取以下内容,例如使用 windows msvc 使用的间接级别比我在大多数地方看到的要高。

#    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))

传递给仅应用外部 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 中工作,但正在转换为"\\"- 使用/for path 效果更好

使用字符串表比使用图标更容易查看输出

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))
于 2015-09-30T22:22:02.293 回答
-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"

您必须确保文件的其余部分正确展开。执行“man m4”以获取更多信息。

于 2012-11-23T21:51:51.807 回答
-1

老实说,我会避免使用预处理器执行此操作。调试预处理器错误是一件痛苦的事,我见过使用多层预处理器替换和连接的情况,在尝试查找问题时导致灾难。只是我的2美分。

于 2012-11-22T15:05:16.763 回答