[Update]
- the code given does actually work. I was mistaken when I thought that it did not. My bad; sorry++. If you can improve the code, please do so at https://codereview.stackexchange.com/questions/150480/generic-enum-to-text-lookup-in-c
- We must declare our strings at compile time. We code embedded systems and are not allowed to
malloc()
. Sorry for not being so clear.
[Update++] I will probably accept one of the answers below. I forgot to state, though, that our enums are non-contiguous and have a wide range, which can make a difference
The intertubes, and this site, are awash with questions asking for to get text from an enum.
I cannot find a canonical way to do this (and would accept one as answer to this question), so let's see if we can cobble one together between us.
Throughout our code, we have multiple arrays of structures, containing pairs of enums and corresponding strings.
The problem is that the strings have different lengths, so we code a lookup function for each one, which for loops over an array of structures, trying to match the enum and returning the corresponding text if a match is found.
Let’s take the following two contrived examples:
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=
typedef enum
{
north,
south,
east,
west
} E_directions;
struct direction_datum
{
E_directions direction;
char direction_name[6];
};
struct direction_datum direction_data[] =
{
{north, "north"},
{south, "south"},
{east, "east"},
{west, "west"},
};
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=
typedef enum
{
hearts,
spades,
diamonds,
clubs,
} E_suits;
struct suit_datum
{
E_suits suit;
char suit_name[9];
};
struct suit_datum suit_data[] =
{
{hearts, "hearts"},
{spades, "spades"},
{diamonds, "diamonds",},
{clubs, "clubs"},
};
Apart from the string length, they are similar/identical, so, in theory, we should be able to code a generic function to loop over either direction_data
or suit_data
, given an index and return the corresponding text.
I am thinking something like this – but it doesn’t work (the enum value in the struct always seems to be zer0, so obviously my pointer arithmetic is off).
What am I doing wrongly?
char *Get_text_from_enum(int enum_value,
void *array,
unsigned int array_length,
unsigned int size_of_array_entry)
{
unsigned int i;
unsigned int offset;
for (i = 0; i < array_length; i++)
{
offset = i * size_of_array_entry;
if ((int) * ((int *) (array+ offset)) == enum_value)
return (char *) (array + offset + sizeof(int));
}
return NULL;
}
printf("Expect south, got %s\n",
Get_text_from_enum(south,
direction_data,
ARRAY_LENGTH(direction_data),
sizeof(direction_data[0])));
printf("Expect diamonds, got %s\n",
Get_text_from_enum(diamonds,
suit_data,
ARRAY_LENGTH(suit_data),
sizeof(suit_data[0])));