在c ++中将char *转换为enum

时间:2015-02-18 22:28:51

标签: c++ c enums

我想将char *转换为enum,因此我使用this。但我在将char *转换为enum

时遇到错误

我无法更改enum。同样type[]是动态的,用于简化我正在显示静态值。

enum type_t {
    MSG_1 = 0,
    MSG_2
};

char type[] = "MSG_1|MSG_2";
char *type_char;
type_char = strtok (type,"|");
while (type_char != NULL)
{
    type_t type_enum = static_cast<type_t >(type_char );
    type_char = strtok (NULL, "|;");
}

我收到以下错误

error: invalid static_cast from type 'char*' to type 'type_t'

我想将char *转换为enum

4 个答案:

答案 0 :(得分:5)

与其他具有更强运行时“反射”功能的语言不同,在C ++中enum是纯粹的编译时工件。编译完成后,无法获取枚举常量的名称。调试器可以通过读取编译器为调试器准备的特殊表来获取它们,但访问这些文件会适得其反。

如果您希望能够将枚举名称转换为其值,请从unordered_mapstring创建enum,静态填充,并根据需要执行查找:< / p>

static std::unordered_map<std::string,type_t> nameToTypeT;
...
nameToTypeT["MSG_1"] = MSG_1;
nameToTypeT["MSG_2"] = MSG_2;
...
type_t = nameToTypeT[std::string(type_char)];

答案 1 :(得分:2)

您必须编写将字符串中的文本转换为相关枚举值的代码。

我通常通过沿着以下几行编写函数来实现这一点:

type_t str_to_type_t(const char *str)
{
#define X(x) { #x, x }
  struct entry
  {
     const char *name;
     type_t value;
  };
  entry table[] = {
      X(MSG_1),
      X(MSG_2)
  };

  for(auto e : table)
  {
     if (strcmp(e.name, s) == 0)
       return e.value;
  }
  return -1;   // Or MSG_UNKNOWN or similar. 
}

如果有大量枚举,那么使用std::map<std::string, type_t> table;然后使用if ((auto it = table.find(s)) != table.end()) { return it->second; [或unordered_map,也许是更好的解决方案,但对于少数枚举,它几乎没有差。

答案 2 :(得分:1)

以下是一个例子:

struct entry_t
{
   type_t      value;
   const char *literal;
};
static const entry_t table[] =
{
   {MSG_1, "MSG1"},
   {MSG_2, "MSG2"},
};

type_t typeFromLiteral(const char *literal)
{
   for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i)
   {
     if (0 == strcmp(table[i].literal, literal))
     {
        return table[i].value;
     }
   };
   abort();
}

答案 3 :(得分:0)

您无法从char *投射到enum,它们是不兼容的类型。你有三个选择

  1. 使用

    if (strcmp(textualRepresentation, "EnumValue1") == 0)
         return EnumValue1;
    else if (strcmp(textualRepresentation, "EnumValue2") == 0)
         return EnumValue2;
    
  2. 创建一个包含文本表示和enum值的结构,然后使用bsearch()匹配文本表示并检索enum值。

    struct EnumData {
        const char *name;
        Enum value;
    };
    
    EnumData enums[ENUM_COUNT] = {
        {"EnumValue1", EnumValue1},
        {"EnumValue2", EnumValue2}
    };
    
    int compare_enums(const void *const lhs, const void *const rhs)
    {
        return strcmp(reinterpret_cast<const EnumData *>(lhs)->name,
                      reinterpret_cast<const EnumData *>(rhs)->name);
    }
    

    然后像这样搜索

    EnumData  key;
    void     *found;
    
    key.name = "EnumValue2";
    found    = bsearch(&key, enums, ENUM_COUNT, sizeof(EnumData), compare_enums);
    if (found != NULL)
        std::cout << reinterpret_cast<EnumData *>(found)->value << " is the enum value" << std::endl;
    
  3. 使用std::map<const char *,Enum>,这是最佳选择。

  4. 以下代码演示了方法2和3,方法1很明显

    enum Enum {
        InvalidEnumValue,
        EnumValue1,
        EnumValue2,
        EnumCount
    };
    
    struct EnumData {
        const char *name;
        Enum        value;
    };
    
    static EnumData enums[EnumCount] = {
        {"EnumValue1", EnumValue1},
        {"EnumValue2", EnumValue2},
        {"InvalidEnumValue", InvalidEnumValue}
    };   
    
    int compare_enums(const void *const lhs, const void *const rhs)
    {
        return strcmp(reinterpret_cast<const EnumData *>(lhs)->name,
                      reinterpret_cast<const EnumData *>(rhs)->name);
    }
    
    Enum find_enum_value_with_bsearch(const char *const name)
    {
        EnumData  key;
        void     *found;
    
        key.name = name;
        found    = bsearch(&key, enums, EnumCount, sizeof(EnumData), compare_enums);
        if (found == NULL)
            return InvalidEnumValue;
        return reinterpret_cast<EnumData *>(found)->value;
    }
    
    
    int
    main()
    {
        Enum                        value;
        std::map<const char *,Enum> enumsMap;
    
        enumsMap["EnumValue1"] = EnumValue1;
        enumsMap["EnumValue2"] = EnumValue2;
    
        value = find_enum_value_with_bsearch("EnumValue2");
    
        std::cerr << value << std::endl;
        std::cerr << enumsMap["EnumValue1"] << std::endl;
    }