简体   繁体   中英

Search enum by name with a variable?

If I have that code:

enum {
    blue,
    red,
    //...
}

main(){

    char * color;
    color = (char * )malloc.....
    getString(&color);
// Now let say color = "red"
printf("%d",function_to_search_enums_by_name_and_returing_them(color));
    // '1' will be printed
}

Is there any (not to complicated) way to achieve that?

  • I know I can use if 's/ switch , and just cover all option of the enum . Anything "better" then that?

One way to achieve this would be

#include <stdio.h>

#define FOREACH_COLOR(FUNC) \
         FUNC(BLUE) \
         FUNC(RED) \
         /* ... */
#define GENERATE_ENUM(val) val, 
#define GENERATE_STRING(val) #val,

int main(int argc, char **argv) {
    enum colors {
            FOREACH_COLOR(GENERATE_ENUM)
    };
    const char *color_strings[] = {
            FOREACH_COLOR(GENERATE_STRING)
    };

    printf("Key: %d, String: %s", BLUE, color_strings[BLUE]);
    /*
     * Output will be:
     * Key: 0, String: BLUE
     */

    return (0);
}

To get the enum value of a given string, do a lookup in color_strings and return the enum value (didn't test that code):

int get_enum_value_from_string(const char **color_strings, const size_t strings_cnt,
                               const char *color) {
    int i;
    for (i = 0; i < strings_cnt; ++i) { /* for each color */
        if (strcmp(color, color_strings[i]) == 0) { 
            /* if the given string matches an entry in the color array */
            return (i); /* this is the droid we're looking for! */
        }
    }
    return (-1); /* not found */
}
#include <stdio.h>
#include <string.h>



typedef enum{
    RED     =   0xff,
    GREEN   =   0xff00,
    BLUE    =   0xff0000
}PRE_DEFINED_COLORS;

typedef struct{
    int         color_val;
    char        *color_name;
}COLOR_ENTRY;

#define COLOR_ITEM(a)    {a, #a}

COLOR_ENTRY color_entries[]={
    COLOR_ITEM(RED),
    COLOR_ITEM(GREEN),
    COLOR_ITEM(BLUE)
};

#define DEFINED_COLOR_COUNT (sizeof(color_entries)/sizeof(*color_entries))

int GetEnumValue(const char *color_name , int errval){
    for(int i = 0 ; i < DEFINED_COLOR_COUNT ; i++)
        if(!strcmp(color_entries[i].color_name , color_name))
            return color_entries[i].color_val;

    //in case not found return errval
    return errval;
}

const char *GetEnumName(int color_val){
    for(int i = 0 ; i < DEFINED_COLOR_COUNT ; i++)
        if(color_entries[i].color_val == color_val)
            return color_entries[i].color_name;

    //no match, return NULL
    return NULL;
}



int main(void){

    printf("Printing defined color table (by index):\n");

    for(int i = 0 ; i < DEFINED_COLOR_COUNT ; i++){
        printf(" %d - %-8s= %06X\n", i , color_entries[i].color_name , color_entries[i].color_val);
    }

    printf("\nPrinting color values by name:\n");

    printf(" *   %-8s= %06X\n",    "RED",      GetEnumValue("RED",     -1));
    printf(" *   %-8s= %06X\n",    "GREEN",    GetEnumValue("GREEN",   -1));
    printf(" *   %-8s= %06X\n",    "BLUE",     GetEnumValue("BLUE",    -1));

    // this item do not exists, this will return -1 (0xFFFF:FFFF)
    printf(" *   %-8s= %06X\n",    "YELLOW",   GetEnumValue("YELLOW",  -1));

    return 0;
}

If you're programming pure C, and want to use a string as a key to a corresponding enum you have to use a set of "if's" with strcmp from "string.h".

If you may use C++ I advise you to use a std::map with a pair of "std::string" and "int". You can use the string as a key, the result will be much more clear than any C approach.

EDIT: you call also use your enum as the second elemento of the map, if you wish

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM