Eu uso algo assim:
em um arquivo "EnumToString.h":
#undef DECL_ENUM_ELEMENT
#undef DECL_ENUM_ELEMENT_VAL
#undef DECL_ENUM_ELEMENT_STR
#undef DECL_ENUM_ELEMENT_VAL_STR
#undef BEGIN_ENUM
#undef END_ENUM
#ifndef GENERATE_ENUM_STRINGS
#define DECL_ENUM_ELEMENT( element ) element,
#define DECL_ENUM_ELEMENT_VAL( element, value ) element = value,
#define DECL_ENUM_ELEMENT_STR( element, descr ) DECL_ENUM_ELEMENT( element )
#define DECL_ENUM_ELEMENT_VAL_STR( element, value, descr ) DECL_ENUM_ELEMENT_VAL( element, value )
#define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
#define END_ENUM( ENUM_NAME ) ENUM_NAME; \
const char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);
#else
#define BEGIN_ENUM( ENUM_NAME) const char * GetString##ENUM_NAME( enum tag##ENUM_NAME index ) {\
switch( index ) {
#define DECL_ENUM_ELEMENT( element ) case element: return #element; break;
#define DECL_ENUM_ELEMENT_VAL( element, value ) DECL_ENUM_ELEMENT( element )
#define DECL_ENUM_ELEMENT_STR( element, descr ) case element: return descr; break;
#define DECL_ENUM_ELEMENT_VAL_STR( element, value, descr ) DECL_ENUM_ELEMENT_STR( element, descr )
#define END_ENUM( ENUM_NAME ) default: return "Unknown value"; } } ;
#endif
então, em qualquer arquivo de cabeçalho, você faz a declaração enum, day enum.h
#include "EnumToString.h"
BEGIN_ENUM(Days)
{
DECL_ENUM_ELEMENT(Sunday)
DECL_ENUM_ELEMENT(Monday)
DECL_ENUM_ELEMENT_STR(Tuesday, "Tuesday string")
DECL_ENUM_ELEMENT(Wednesday)
DECL_ENUM_ELEMENT_VAL_STR(Thursday, 500, "Thursday string")
}
END_ENUM(MyEnum)
em seguida, em um arquivo chamado EnumToString.c:
#include "enum.h"
#define GENERATE_ENUM_STRINGS
#include "enum.h"
#undef GENERATE_ENUM_STRINGS
então em main.c:
int main(int argc, char* argv[])
{
Days TheDay = Monday;
printf( "%d - %s\n", TheDay, GetStringDay(TheDay) );
TheDay = Thursday;
printf( "%d - %s\n", TheDay, GetStringDay(TheDay) );
return 0;
}
isto irá gerar "automaticamente" as strings para quaisquer enums declarados desta forma e incluídos em "EnumToString.c"