我正在处理这个项目,我需要解析一个文本文件,其中包含一个由左侧名称和右侧值组成的双列表。
现在,我需要将它们写入控制表中的特定位置,这些位置使用十六进制地址标识;在我无法编辑的头文件中,它们已被定义为:
#define HARRY_POTTER 0x3A
然后有一个写入函数,它接受一个地址和一个值并将其写入存储位置(此功能也不受我的控制)。所以,调用这个
write(0x3A, 7);
与调用此
的结果相同write(HARRY_POTTER, 7);
由于头文件中的定义。
现在,我已经解析了,它基本上给了左列,名称,作为字符串(例如,“HARRY_POTTER”),右列,值,作为整数。
我想知道的是,是否有任何方法可以使用此字符串,“HARRY_POTTER”作为写入函数中的标识符;本质上是将字符串转换为标识符,这样我就可以循环遍历整个解析值数组,并自动将它们写入匹配左列中字符串/名称的地址。
这可能吗?如果是,怎么样?
答案 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
的值发生变化,您的映射代码将在重新编译时自动更新。