将枚举值分配给整数崩溃程序

时间:2014-12-01 19:30:15

标签: c++ casting enums crash

我创建了一个包含这些值的枚举:

enum Car_Manufacturer
{
   AUDI     = 1,
   CHRYSLER = 2,
   FORD     = 3,
   HONDA    = 4,
   LEXUS    = 5,
   NISSAN   = 6,
   MERCEDES = 7,
   PORSCHE  = 8,
   VOLVO    = 9

};

我让用户输入一个与他们想要查看的汽车模型相对应的角色。我需要用户输入的字符变成一个整数,它对应于枚举中的值,这样我就可以轻松搜索数组以找到正确make的汽车。我创建的函数如下所示:

int set_car_make_ch( char input )
{  
   int manufacturer = 0;
   if( input == 'A' )
   {
      manufacturer = AUDI;   
   }
   else if( input == 'C' )
   {
     manufacturer = CHRYSLER;
   }
   else if( input == 'F' )
   {   
      manufacturer = (int)FORD;
   }
   else if( input == 'H' )
   {
     manufacturer = HONDA;
   }
   else if( input == 'L' )
   {
     manufacturer = LEXUS;
   }
   else if( input == 'M' )
   {
     manufacturer = MERCEDES;
   }
   else if( input == 'N' )
   {
     manufacturer = NISSAN;
   }
   else if( input == 'P' )
   {
     manufacturer = PORSCHE;
   }
   else if( input == 'V' )
   {
     manufacturer = VOLVO;
   }
   else
   {
      cout<<"Invalid Car Manufacturer, please edit the input file."<<endl;
      exit( EXIT_FAILURE );
   }
   return manufacturer;
}

当枚举值尝试分配给整数时,程序会冻结并崩溃。我正在使用G ++编译器。对此问题的任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

请使用查找表或switch语句而不是if-else-if梯形图。

查找表

struct Car_Text_Enum_Entry
{
  const char * name;
  Car_Manufacturer enum_value;
};

const static Car_Text_Enum_Entry enum_conversion[] =
{
  {"AUDI", AUDI},
  {"BMW",  BMW},
  {"DODGE", DODGE},
  //...
};
const unsigned int number_of_conversions = 
  sizeof(enum_conversion) / sizeof(enum_conversion[0]);

Car_Manufacturer Car_Text_To_Enum(char car_mfg_letter)
{
  Car_Manufacturer manufacturer = 0;
  for (unsigned int i = 0; i < number_of_conversions; ++i)
  {
    if (enum_conversion[i].name[0] == car_mfg_letter)
    {
      manufacturer = enum_conversion[i].enum_value;
      break;
    }
  }
  return manufacturer;
}

查找表是很多更严格的代码,添加或删除制造商只需要更改表,而不是代码。

转换声明

switch语句方法适用于字母,但不适用于字符串。对于字符串,请使用查找表。

Car_Manufacturer Car_Mfg_Letter_To_Enum(char car_mfg_letter)
{
  Car_Manufacturer manufacturer;
  switch (car_mfg_letter)
  {
    case 'A' : manufacturer = AUDI; break;
    case 'B' : manufacturer = BMW; break;
    case 'D' : manufacturer = DODGE; break;
    case 'H' : manufacturer = HONDA; break;
    // ...
  }
  return manufacturer;
}

switch语句方法比if-else-if梯形图更易读,更易于维护。但是,它不适用于字符串(a.k.a。多个字母)。

地图

但是,如果您已了解std::map,也可以使用它:

typedef std::map<char, Car_Manufacturer> Car_Mfg_Container;
Car_Mfg_Container car_mfg_association;
// Initialization:
car_mfg_association['A'] = AUDI;
car_mfg_association['B'] = BMW;
//...

Car_Manufacturer Car_Mfg_Letter_To_Enum(char car_mfg_letter)
{
  return car_mfg_association[car_mfg_letter];
}

与静态,常量,查找表不同,std::map必须在运行时初始化。

所以,请不要将if-else-if梯子用于可以在表格中查找的内容。

此外,使用枚举,您只需要为第一个项目指定值。

答案 1 :(得分:0)

你还没有解释你得到的错误信息(如果有的话)或者你如何使用这个函数,但是从enum依赖隐式或C风格的转换通常不是一个好主意。 {1}}当你有更好的C ++工具时:

试试这个:将变量声明为int类型:

Car_Manufacturer

如果出于某种原因必须使用Car_Manufacturer manufacturer{}; ,请尝试以下操作:

int

如果还有其他错误,而不是因为你正在做一个明确的C风格演员而崩溃,你应该从manufacturer = static_cast < int >(FORD); 得到一个合理的错误信息。

完全避免此类问题的最佳方法是使用C11's Scoped enumerations,它们是强类型的,不能简单地转换为整数。

(另外,正如@ThomasMatthews所解释的那样,当你有static_castswitch或{{1}时,请使用if/else if,而不是enum }。)