是否有一种方便的方法来获取字符串(由用户输入)并将其转换为枚举值?在这种情况下,字符串将是枚举值的名称,如下所示:
enum Day
{
Sunday = 0,
Monday = 1,
...
}
因此,如果用户给出了 Day 的名称,它将能够将其解析为相应的 Enum 值。
诀窍是,我正在使用超过 500 个值,它们分布在多个枚举中。
我知道 c# 中的 Enum.Parse 方法,那么 c 中有某种形式吗?
实现它的标准方法是:
typedef enum {value1, value2, value3, (...) } VALUE;
const static struct {
VALUE val;
const char *str;
} conversion [] = {
{value1, "value1"},
{value2, "value2"},
{value3, "value3"},
(...)
};
VALUE
str2enum (const char *str)
{
int j;
for (j = 0; j < sizeof (conversion) / sizeof (conversion[0]); ++j)
if (!strcmp (str, conversion[j].str))
return conversion[j].val;
error_message ("no such string");
}
反之亦然。
没有直接的方法,但是使用 C,您可以即兴发挥。这是一个老把戏。纯粹主义者可能会对此犹豫不决。但这是一种稍微理智地管理这类事情的方法。使用一些预处理器技巧。
在 constants.h 中输入以下内容:
CONSTANT(Sunday, 0)
CONSTANT(Monday, 1)
CONSTANT(Tuesday, 2)
在 main.c 中:
#include <stdio.h>
#define CONSTANT(name, value) \
name = value,
typedef enum {
#include "constants.h"
} Constants;
#undef CONSTANT
#define CONSTANT(name, value) \
#name,
char* constants[] = {
#include "constants.h"
};
Constants str2enum(char* name) {
int ii;
for (ii = 0; ii < sizeof(constants) / sizeof(constants[0]); ++ii) {
if (!strcmp(name, constants[ii])) {
return (Constants)ii;
}
}
return (Constants)-1;
}
int main() {
printf("%s = %d\n", "Monday", str2enum("Monday"));
printf("%s = %d\n", "Tuesday", str2enum("Tuesday"));
return 0;
}
您可以尝试基本思想的其他变体。
警告,这是一个彻头彻尾的黑客攻击。您可以使用它dlsym
来查找已适当初始化的变量。为了使这个示例能够正常工作,您必须进行编译以允许动态链接器可以看到局部符号。使用 GCC,选项是-rdynamic
.
enum Day {
SunDay, MonDay, TuesDay, WednesDay, ThursDay, FriDay, SaturDay
};
enum Day Sunday = SunDay,
Monday = MonDay,
Tuesday = TuesDay,
Wednesday = WednesDay,
Thursday = ThursDay,
Friday = FriDay,
Saturday = SaturDay;
int main () {
const char *daystr = "Thursday";
void *h = dlopen(0, RTLD_NOW);
enum Day *day = dlsym(h, daystr);
if (day) printf("%s = %d\n", daystr, *day);
else printf("%s not found\n", daystr);
return 0;
}
如果您使用的是直接 C,则没有“Enum.Parse”等价物。您需要编写自己的函数,将用户的字符串与预定义的值进行比较strcmp()
,然后返回适当的枚举值。
另一种可能性是使用现有的“哈希映射”实现,或者滚动你自己的实现——例如,glib 中的那个应该适合你:https ://developer.gnome.org/glib/2.30/glib-Hash-Tables.html
哈希映射应该比对可能的枚举值进行线性搜索要快,如果你有很多枚举值(例如,如果你做的事情不是一周中的几天)。一个好的哈希映射实现应该接近于 O(1) 的查找,而不是 O(n) 的线性搜索。
并非如此,但如果您使用散列函数,您可以设置枚举的所有值以匹配一组散列字符串。如果您不关心区分大小写,则可能必须使用更复杂的哈希。
这可能是您最好的解决方案,因为它的开销低于 strcmp (...)。从字符串哈希分配枚举值不需要重复的字符串比较等...
那将是一个很好的解决方案:
enum e_test { a, b, c, END };
enum e_test get_enum_value(char * val) {
static char const * e_test_str[] = { "a", "b", "c" };
for (int i = 0; i < END; ++i)
if (!strcmp(e_test_str[i], val))
return i;
return END;
}