Obtenir la valeur enum par nom

J’ai une énumération, qui contient des centaines d’entrées.

Je vais obtenir la valeur de l’énumération sous forme de chaîne. Est-il possible de convertir la chaîne en une valeur enum? Sinon, je finirai par utiliser des centaines de déclarations if.

Considérer

enum Colors { Red, Green, Blue, Yellow ... } there are more than 100 ensortinges 

Je vais obtenir "Red" dans une variable de chaîne,

 Ssortingng color = "Red"; // "Red" would be generated dynamically. 

Normalement, nous accédons à l’énumération de la manière suivante: Colors::Red , Colors::Blue etc … existe-t-il un moyen d’y accéder de la manière suivante:

 Colors::color; // ie enumtype::ssortingngVariable 

Dans beaucoup de posts ici, il est donné que nous pouvons utiliser map, mais encore une fois, lors de la construction de map, nous finirons par utiliser des centaines de if .

y-a-t-il un moyen d’éviter ça?

Voici une façon de le faire, similaire à la carte C ++ de Paddy. La macro garantit que le nom et l’énumération correspondante sont liés.

 enum Colors { NoColor, Red, Green, Blue, Yellow }; enum Colors get_color(const char *s) { const struct { char *name; enum Colors color; } colormap[] = { #define Color(x) {#x, x} Color(Red), Color(Green), Color(Blue), Color(Yellow) #undef Color }; for (size_t i = 0; i < sizeof colormap / sizeof colormap[0]; ++i) { if (!strcmp(s, colormap[i].name)) { return colormap[i].color; } } return NoColor; } 

EDIT Comme @ sh1 le suggérait dans un commentaire (qui a maintenant disparu), vous pouvez utiliser une macro X pour définir la liste de couleurs. Cela évite de définir deux fois la liste. Voici l'exemple ci-dessus réécrit en utilisant une macro X - grâce à sh1 pour le conseil:

 #define COLORS X(Red), X(Green), X(Blue), X(Yellow), enum Colors { NoColor, #define X(x) x COLORS #undef X }; enum Colors get_color(const char *s) { const struct { char *name; enum Colors color; } colormap[] = { #define X(x) {#x, x} COLORS #undef X }; ...etc 

Utilisez la technique X-macro . Transcrivant presque directement à partir de Wikipedia:

 #define LIST_OF_COLORS \ X(Red) \ X(Green) \ X(Blue) \ X(Yellow) #define X(name) name, enum Colors { LIST_OF_COLORS }; #undef X #define X(name) #name, char const * const ColorName[] = { LIST_OF_COLORS }; #undef X 

Parce que les énumérations assignent automatiquement des valeurs à partir de zéro et que nous ne pouvons pas répéter la liste accidentellement dans un ordre différent lorsque nous créons le tableau de noms, utiliser enum comme index dans le tableau ColorName pointe toujours ne pas avoir à rechercher lors de la cartographie dans cette direction. Alors:

 printf("%s\n", ColorName[Red]); 

Imprimera:

 Red 

Et en allant dans l’autre sens:

 enum Color strtoColor(char const *name) { for (int i = 0; i < sizeof(ColorName) / sizeof(*ColorName); i++) if (strcmp(ColorName[i], name) == 0) return (enum Color)i; return -1; } 

MODIFIER

Si vous utilisez C ++, alors, en utilisant X-macro sur la réponse de paddy:

 static std::map colorMap; void InitColorMap() { #define X(name) colorMap[#name] = name; LIST_OF_COLORS #undef X } 

Ou, dérobant cette réponse , en C ++ 11:

 static std::map colorMap = { #define X(name) { #name, name }, LIST_OF_COLORS #undef X }; 

... ou peu importe. Ce n'est pas ma langue.

C’est un peu un bidouillage, mais si vous utilisez du C pur, vous pourriez faire ce qui suit:

 char* ssortingngArray[]={"Red", "Green", "Blue", "Yellow"}; 

Ensuite, vous pouvez trouver la chaîne correspondante en bouclant sur le tableau jusqu’à ce que vous trouviez une correspondance:

 for(ii = 0; ii < size(stringArray); ii++) { if (strcmp(inputString, stringArray[ii]) == 0) { // you found it! } } 

Ce n’est pas clair si vous utilisez C ou C ++ ici.

Une façon de résoudre ce problème consiste à utiliser une macro avec l’opérateur ssortingngize. Quelque chose comme ça:

 #define RegisterColor(c) colorMap[#c] = (c) 

Dans ce cas, j’ai supposé quelque chose comme une map C ++:

 enum Colors { .... }; static std::map colorMap; void InitColorMap() { RegisterColor(Red); RegisterColor(Green); RegisterColor(Blue); RegisterColor(Yellow); // ... } 

Il y a un peu de répétition, mais si vous avez besoin de l’ enum vous ne pouvez pas l’éviter.

Il est assez facile d’utiliser le même principe en C, en utilisant votre propre structure de données.