(如何)我可以在C ++中使用字符串数组作为标识符?

时间:2014-07-11 12:56:00

标签: c++ string c-preprocessor identifier

我正在处理这个项目,我需要解析一个文本文件,其中包含一个由左侧名称和右侧值组成的双列表。

现在,我需要将它们写入控制表中的特定位置,这些位置使用十六进制地址标识;在我无法编辑的头文件中,它们已被定义为:

#define HARRY_POTTER 0x3A

然后有一个写入函数,它接受一个地址和一个值并将其写入存储位置(此功能也不受我的控制)。所以,调用这个

write(0x3A, 7);

与调用此

的结果相同
write(HARRY_POTTER, 7);

由于头文件中的定义。

现在,我已经解析了,它基本上给了左列,名称,作为字符串(例如,“HARRY_POTTER”),右列,值,作为整数。

我想知道的是,是否有任何方法可以使用此字符串,“HARRY_POTTER”作为写入函数中的标识符;本质上是将字符串转换为标识符,这样我就可以循环遍历整个解析值数组,并自动将它们写入匹配左列中字符串/名称的地址。

这可能吗?如果是,怎么样?

2 个答案:

答案 0 :(得分:4)

不,你问的不可能。原因是因为从文件中读取的字符串仅在运行时已知,而预处理在编译时发生,因此HARRY_POTTER必须已被替换。事实上,在编译程序之后根本就没有标识符。

您可能希望它引入从std::string s到您定义的常量的映射。例如:

std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", HARRY_POTTER},
                                                {"RON_WEASLEY", RON_WEASLEY}};

当然,常量会在编译时被替换,所以这只相当于:

std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", 0x3A},
                                                {"RON_WEASLEY", 0x7C}};

然后您可以使用以下方式致电write

write(mapping.at(key), 7);

其中key是一个字符串,其值为"HARRY_POTTER"

答案 1 :(得分:2)

(这个答案在评论中更适合,但我仍在努力提高声誉......)

我同意Joseph的观点,那就是C ++ 11中的std :: unordered_map或C ++ 03中的std :: map。

我只想补充一点,在这种情况下,您可以通过一些宏魔法使代码更易于维护和编写。

/* The stringify macro converts x to "x" at compile-time. */
#define _stringify(x) # x
#define stringify(x) _stringify(x)

/* Macro easing the assignment of { "String", value } */
#define STR_VAL(x) { stringify(x), (x) }

/* Now you can write the assignment code as follows */
std::unordered_map<std::string, int> mapping = {
    STR_VAL(HARRY_POTTER),
    STR_VAL(RON_WEASLEY),                                                          
    STR_VAL(ALBUS_BRIAN_WULFRIC_PERCIVAL_DUMBLEDORE)
};

这意味着如果#define HARRY_POTTER的值发生变化,您的映射代码将在重新编译时自动更新。