tags:

views:

128

answers:

3

Is there a way to display the name of an enum's value? say we have:

enum fuits{
    APPLE,
    MANGO,
    ORANGE,
};

main(){
enum fruits xFruit = MANGO;
...
printf("%s",_PRINT_ENUM_STRING(xFruit));
...
}

using the preprocessor

#define _PRINT_ENUM_STRING(x) #x

won't work as we need to get the value of the variable 'x' and then convert It to string. Is this at all possible in c/C++?

+1  A: 

You can use a mapping in this case.

char *a[10] = { "APPLE","MANGO","ORANGE"};

printf("%s",a[xFruit]);

Yes the preprocessor won't work unless you provide the exact enum -value.

Also check this question for more insights.

Praveen S
+5  A: 
schot
This is the best way I know. I've used a similar technique for error strings with a 2-argument X macro: `X(name,desc)` where the macro expanded to either the error code (analogous to `errno` values) or a descriptive string depending on where the error list file was included.
R..
+1. This nearly beats my usual hack of defining the enum in a perl script that writes the enum to a .h file and the matching translation array to a .c file. My way requires a custom build step which is easy with make, but harder in a full IDE.
RBerteig
I don't like it. Can be useful sometimes, but I would not overuse it. Maybe I would use it for big and frequently changed enums. The costs of this are too big.
adf88
...Extra header file, scattered includes, use of preprocessor. You can make mistakes because of them. For small and medium enums it's better to write the lookup table by yourself, near the enum declaration.
adf88
...There are techniques that reduce a risk of lookup table being desynchronized like defining inside an enum the first and the last markers, then putting static assert on lookup table size depending on these markers. Usually these markers are helpful for other purposes so this is not an additional mess just to keep lookup table synchronized.
adf88
@adf88 See added last paragraph for a version without extra header files or scattered includes.
schot
That's better :). Anyway, this is worth to be mentioned solution.
adf88
A: 

I've used preprocessor programming successfully to get a macro of this kind:

DEFINE_ENUM(Fruits, (Apple)(Mango)(Orange));

It does a tad more than just printing the names, but it could easily be simplified to 2 switches if necessary.

It's based on Boost.Preprocessor facilities (notably BOOST_PP_SEQ_FOREACH) which is a must have for preprocessor programming, and I find it much more elegant than the X facility and its file reinclusion system.

Matthieu M.