显示枚举值名称的通用方法

时间:2010-08-11 06:52:26

标签: c++ c

有没有办法显示枚举值的名称? 说我们有:

enum fuits{
    APPLE,
    MANGO,
    ORANGE,
};

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

使用预处理器

#define _PRINT_ENUM_STRING(x) #x

将无法正常工作,因为我们需要获取变量'x'的值,然后将其转换为字符串。 这在c / C ++中是否可行?

4 个答案:

答案 0 :(得分:7)

您可以使用预处理器来执行此操作,我相信此技术称为X-Macros

/* fruits.def */
X(APPLE)
X(MANGO)
X(ORANGE)

/* file.c */
enum fruits {
#define X(a) a,
#include "fruits.def"
#undef X
};

const char *fruit_name[] = {
#define X(a) #a,
#include "fruits.def"
#undef X
};

请注意,最后一个条目包含一个尾随逗号,在C99中允许使用(但在C89中不允许)。如果这是一个问题,您可以添加sentinal值。通过为自定义名称或枚举值等提供多个参数,也可以使宏更复杂:

X(APPLE, Apple, 2)
#define X(a,b,c) a = c,        /* in enum */
#define X(a,b,c) [c] = #b,     /* in name array */

限制:你不能有负常数,你的数组是sizeof (char *) * largest_constant但你可以通过使用额外的查找表来解决这两个问题:

int map[] = {
#define X(a,b,c) c,
#include "fruits.def"
#undef X
};

<击>

这当然不起作用。什么工作是生成一组额外的enum常量作为名称的键:

enum fruits {
#define X(a,b,c) a ## _KEY,
#include "fruits.def"
#undef X
#define X(a,b,c) a = c,
#include "fruits.def"
#undef X
};

现在,您可以使用X(PINEAPPLE, Pineapple, -40)找到fruit_name[PINEAPPLE_KEY]的名称。

人们注意到他们不喜欢额外的包含文件。您不需要这个额外的文件,也使用#define。这可能更适合小型列表:

#define FRUIT_LIST X(APPLE) X(ORANGE)

在前面的示例中将#include "fruits.def替换为FRUIT_LIST

答案 1 :(得分:1)

在这种情况下,您可以使用映射。

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

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

是的,除非您提供确切的枚举值,否则预处理器将无法工作。

另请查看this question以获取更多见解。

答案 2 :(得分:0)

我已成功使用预处理程序编程来获取此类宏:

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

它不仅仅是打印名称,还可以在必要时轻松简化为2个开关。

它基于Boost.Preprocessor工具(特别是BOOST_PP_SEQ_FOREACH),它是预处理器编程必备的工具,我发现它比X工具及其文件重新封装系统更优雅。

答案 3 :(得分:-1)

 public enum LDGoalProgressUpdateState
    {

    [Description("Yet To Start")]
    YetToStart = 1,
    [Description("In Progress")]
    InProgress = 2,
    [Description("Completed")]
    Completed = 3
}


    var values = (ENUMList[])Enum.GetValues(typeof(ENUMList));
    var query = from name in values
                select new EnumData//EnumData is a Modal or Entity
                {
                    ID = (short)name,
                    Name = GetEnumDescription(name)//Description of Particular Enum Name
                };
    return query.ToList();

region HelperMethods

public static string GetEnumDescription(Enum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) return attributes[0].Description; else return value.ToString(); } #endregion