为C中的typedef枚举添加预定义数据

为C中的typedef枚举添加预定义数据,c,enums,typedef,C,Enums,Typedef,在C中为typedef枚举定义附加数据的最佳方法是什么 例如: typedef enum { kVizsla = 0, kTerrier = 3, kYellowLab = 10 } DogType; 现在我想为每一个定义名称,例如kVizsla应该是“vizsla”。 我目前使用的函数使用大开关块返回字符串。这是一个开放式问题,但有一个建议是使用一个映射,将枚举作为键类型,并在值中包含额外信息。(与示例不同,如果索引是连续的,则可以使用序列容器而不是映射)。如果枚举值足够密集,则

在C中为typedef枚举定义附加数据的最佳方法是什么

例如:

typedef enum {
  kVizsla = 0,
  kTerrier = 3,
  kYellowLab = 10
} DogType;
现在我想为每一个定义名称,例如
kVizsla
应该是“vizsla”。
我目前使用的函数使用大开关块返回字符串。

这是一个开放式问题,但有一个建议是使用一个映射,将枚举作为键类型,并在值中包含额外信息。(与示例不同,如果索引是连续的,则可以使用序列容器而不是映射)。

如果枚举值足够密集,则可以定义一个数组来保存字符串并仅查找它们(对任何跳过的值使用NULL,并在查找例程中添加特殊的大小写处理程序)

这对于稀疏枚举是低效的

即使枚举不是稠密的,也可以使用结构数组来保存映射

typedef struct DogMaps {
  DogType index;
  char * name;
} DogMapt;
DogMapt DogMap[] = {
  {kVizsla, "vizsla"},
  {kTerrier, "terrier"},
  {kYellowLab, "yellow lab"},
  NULL
};
第二种方法非常灵活,但它确实意味着每次需要使用数据时都要通过映射进行搜索。对于大型数据集,考虑B-树或哈希而不是数组。

这两种方法都可以推广到连接更多数据。在第一种方法中使用结构数组,在第二种方法中只需向结构添加更多成员

当然,您需要编写各种处理程序来简化与这些数据结构的交互


@好时一定要把代码和数据分开。上述示例旨在说明问题,而非功能性问题

我羞于承认,我仍然使用空格分隔的平面文件,而不是您展示的那种结构化输入,但我的生产代码将尽可能多地从外部源读取数据


等等,我明白你的意思是代码生成

当然。这没什么错


我怀疑,虽然OP对生成的代码应该是什么样子感兴趣…

@dmckee:我认为建议的解决方案是好的,但对于简单的数据(例如,如果只需要名称),它可以用自动生成的代码进行扩充。虽然有很多方法可以自动生成代码,但对于像这样简单的事情,我相信您可以编写一个简单的XSLT,它接受枚举的XML表示并输出代码文件

XML的形式如下:

<EnumsDefinition>
    <Enum name="DogType">
        <Value name="Vizsla" value="0" />
        <Value name="Terrier" value="3" />
        <Value name="YellowLab" value="10" />
    </Enum>
</EnumsDefinition>

由此产生的代码将类似于dmckee在其解决方案中提出的代码

有关如何编写这样一个XSLT的信息,请尝试或在google中搜索它,并找到适合的教程。在我看来,编写XSLT并不有趣,但也没那么糟糕,至少对于这样相对简单的任务来说是这样。

非常适合。这些类型的宏可以使用C预处理器从同一源构造枚举和数组。只需将新数据添加到包含X()宏的#define

您的示例可以编写如下:

// All dog data goes in this list
#define XDOGTYPE \
  X(kVizsla,0,"vizsla") \
  X(kTerrier,3,"terrier") \
  X(kYellowLab,10,"yellowlab")

 // Dog info
 typedef struct {
     int val;       // Defined value
     char * desc;   // Text description
 } DogType;

 // Build an array index using the Names
 typedef enum {
  #define X(Name,Val,Text)     Name,
   XDOGTYPE
  #undef X
  MAXDOGS
 } DogIndex;

 // Build a lookup table of values
 DogType Dog[] = {
  #define X(Name,Val,Text)    {Val,Text},
   XDOGTYPE
  #undef X
 };

 // Access the values
 for (i=0; i < MAXDOGS; i++)
    printf("%d: %s\n",Dog[i].val,Dog[i].desc);
//所有狗的数据都在这个列表中
#定义XDOGTYPE\
X(kVizsla,0,“vizsla”)\
X(克特里尔,3,“梗”)\
X(kYellowLab,10,“黄色实验室”)
//狗信息
类型定义结构{
int val;//定义的值
char*desc;//文本描述
}狗型;
//使用名称构建数组索引
类型定义枚举{
#定义X(名称、Val、文本)名称,
XDOGTYPE
#未定义X
马克斯狗
}狗指数;
//构建值的查找表
狗型狗[]={
#定义X(名称,Val,Text){Val,Text},
XDOGTYPE
#未定义X
};
//访问这些值
对于(i=0;i
// All dog data goes in this list
#define XDOGTYPE \
  X(kVizsla,0,"vizsla") \
  X(kTerrier,3,"terrier") \
  X(kYellowLab,10,"yellowlab")

 // Dog info
 typedef struct {
     int val;       // Defined value
     char * desc;   // Text description
 } DogType;

 // Build an array index using the Names
 typedef enum {
  #define X(Name,Val,Text)     Name,
   XDOGTYPE
  #undef X
  MAXDOGS
 } DogIndex;

 // Build a lookup table of values
 DogType Dog[] = {
  #define X(Name,Val,Text)    {Val,Text},
   XDOGTYPE
  #undef X
 };

 // Access the values
 for (i=0; i < MAXDOGS; i++)
    printf("%d: %s\n",Dog[i].val,Dog[i].desc);