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

Assigning enum value to integer crashes program

本文关键字:整数 崩溃 程序 分配 枚举      更新时间:2023-10-16

我创建了一个具有这些值的枚举:

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

我让用户输入一个与他们要查看的汽车型号相对应的字符。我需要用户输入的字符成为与枚举中的值相对应的整数,以便我可以轻松地搜索数组以找到正确品牌的汽车。我创建的函数如下所示:

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++ 编译器。对此问题的任何帮助将不胜感激。

请使用查找表或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阶梯更具可读性和更易于维护。 但是,它不适用于字符串(也称为多个字母)。

地图

但是,如果您了解了 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可以在桌子上查找的东西。

此外,对于枚举,只需为第一项赋值。

您尚未解释您收到什么(如果有的话...)错误消息或您如何使用此函数,但是当您在C++中提供更好的工具时,从enumint依赖隐式或 C 样式转换通常不是一个好主意:

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

Car_Manufacturer manufacturer{};

如果由于某种原因您必须使用int请尝试以下操作:

manufacturer = static_cast < int >(FORD);

如果有其他错误,而不是因为您正在执行显式的 C 样式转换而崩溃,您应该从 static_cast 收到合理的错误消息。

完全避免此类问题的最佳方法是使用 C11 的作用域枚举,这些枚举是强类型,不能简单地转换为整数。

(顺便说一句,正如@ThomasMatthews所解释的,当你有enumcharint时,使用switch,而不是if/else if