Converting C++ enums to strings

2013. 12. 5. 10:12C++


http://www.codeproject.com/Articles/10500/Converting-C-enums-to-strings

Introduction

This code is used to convert a C++ enumeration value to its equivalent string representation. It is useful, for example, to debug your code, or generate trace messages.

Using the code

Create a header file called "EnumToString.h" with the following contents:

// File name: "EnumToString.h"
#undef DECL_ENUM_ELEMENT
#undef BEGIN_ENUM
#undef END_ENUM

#ifndef GENERATE_ENUM_STRINGS
    #define DECL_ENUM_ELEMENT( element ) element
    #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
    #define END_ENUM( ENUM_NAME ) ENUM_NAME; \
            char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);
#else
    #define DECL_ENUM_ELEMENT( element ) #element
    #define BEGIN_ENUM( ENUM_NAME ) char* gs_##ENUM_NAME [] =
    #define END_ENUM( ENUM_NAME ) ; char* GetString##ENUM_NAME(enum \
            tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; }
#endif

Put your enum in a specific header file using a special syntax. For example, the enum:

enum Days
{
   sunday,
   monday,
   tuesday,
   wednesday,
   thursday,
   friday,
   saturday
};

will become a header file called "Days.h" with the following contents:

// File name: "Days.h"
#if ( !defined(DAYS_H) || defined(GENERATE_ENUM_STRINGS) )

#if (!defined(GENERATE_ENUM_STRINGS))
    #define DAYS_H
#endif

#include "EnumToString.h"

///////////////////////////////
// The enum declaration
///////////////////////////////
BEGIN_ENUM(Days)
{
    DECL_ENUM_ELEMENT(sunday),
    DECL_ENUM_ELEMENT(monday),
    DECL_ENUM_ELEMENT(tuesday),
    DECL_ENUM_ELEMENT(wednesday),
    DECL_ENUM_ELEMENT(thursday),
    DECL_ENUM_ELEMENT(friday),
    DECL_ENUM_ELEMENT(saturday)
}
END_ENUM(Days)

#endif // (!defined(DAYS_H) || defined(GENERATE_ENUM_STRINGS))

Include the file "Days.h" everywhere you need the enum Days. Use it like a normal enumeration:

#include "Days.h"

void MyFunction( Days day )
{
    CString message;
    switch( day )
    {
        case monday:
        case tuesday:
        case wednesday:
        case thursday:
        case friday:
        {
            message.Format("Today is %s, I have to work!", 
                           GetStringDays(day) );
        }
        break;

        case saturday:
        case sunday:
        {
            message.Format("Today is %s, very nice!!!", 
                           GetStringDays(day) );
        }
        break;
    }
    AfxMessageBox(message);                       
}

Create a CPP module where the strings associated to enums are actually defined:

// File name: "EnumToString.cpp"

/// The strings associated with the enums are gererated here
/////////////////////////////////////////////////////////////////////
#define GENERATE_ENUM_STRINGS  // Start string generation
#include "Days.h"             
#include "OtherEnum.h"
#include "AnotherOne.h"
#undef GENERATE_ENUM_STRINGS   // Stop string generation


추가

-----------------------------------------


#undef ENUM_ELEMENT
#undef ENUM_ELEMENT2
#undef BEGIN_ENUM
#undef END_ENUM
 
#ifndef GENERATE_ENUM_STRINGS
    #define ENUM_ELEMENT( element ) element
    #define ENUM_ELEMENT2( element, val ) element = val
    #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME
    #define END_ENUM( ENUM_NAME ) ENUM_NAME; \
            extern char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);
#else
    typedef struct { char * desc; int type;} EnumDesc_t;
    #define ENUM_ELEMENT( element ) { #element, (int)(element) }
    #define ENUM_ELEMENT2( element, val ) { #element, val }
    #define BEGIN_ENUM( ENUM_NAME ) EnumDesc_t gs_##ENUM_NAME [] =
    #define END_ENUM( ENUM_NAME ) ; char* GetString##ENUM_NAME(enum tag##ENUM_NAME index) \
			{ for (int i = 0; i < sizeof(gs_##ENUM_NAME)/sizeof(EnumDesc_t); i++) { \
				if ((int)index == gs_##ENUM_NAME [i].type) return gs_##ENUM_NAME [i].desc; } \
			return "Unknown Enum type!!"; }
#endif

 
Your example is now implemented like this:
 

BEGIN_ENUM(Days)
{
    ENUM_ELEMENT2(monday,1000),
    ENUM_ELEMENT(tuesday),
    ENUM_ELEMENT(wednesday),
    ...
}
END_ENUM(Days)