【问题标题】:How do I use an enum value in a switch statement in C++?如何在 C++ 的 switch 语句中使用枚举值?
【发布时间】:2011-03-02 10:34:48
【问题描述】:

我想为switch 语句使用enum 值。是否可以使用 "{}" 中包含的 enum 值作为 switch()" 的选择?

我知道switch() 需要一个integer 值,以便将编程流程引导到适当的case 号码。如果是这种情况,我是否只为enum 语句中的每个常量创建一个变量?

我还希望用户能够选择选项并将该选项传递给switch() 语句。

例如:

cout << "1 - Easy, ";
cout << "2 - Medium, ";
cout << "3 - Hard: ";

enum myChoice { EASY = 1, MEDIUM = 2, HARD = 3 };

cin >> ????

switch(????)
{
case 1/EASY:  // (can I just type case EASY?)
    cout << "You picked easy!";
    break;

case 2/MEDIUM:
    cout << "You picked medium!";
    break;

case 3/HARD: // ..... (the same thing as case 2 except on hard.)

default:
    return 0;
}

【问题讨论】:

  • 所有这些情况 == 1。
  • @Noah:我相信他用斜线表示“一个或另一个”,而不是除法。虽然在数学上你是正确的,但我不认为这是他打算使用的实际代码。

标签: c++ enums switch-statement


【解决方案1】:

您可以像使用整数一样使用枚举值:

myChoice c;

...

switch( c ) {
case EASY:
    DoStuff();
    break;
case MEDIUM:
    ...
}

【讨论】:

    【解决方案2】:

    你在正确的轨道上。您可以将用户输入读入一个整数,然后switch

    enum Choice
    {
      EASY = 1, 
      MEDIUM = 2, 
      HARD = 3
    };
    
    int i = -1;
    
    // ...<present the user with a menu>...
    
    cin >> i;
    
    switch(i)
    {
      case EASY:
        cout << "Easy\n";
        break;
      case MEDIUM:
        cout << "Medium\n";
        break;
      case HARD:
        cout << "Hard\n";
        break;
      default:
        cout << "Invalid Selection\n";
        break;
    }
    

    【讨论】:

    • 应该可能将 i 初始化为一个会遇到default 情况的值,或者一个解释为 I/O 错误的值。
    • typedef enum e { ... }; ?? typedef 在 C++ 中是可选的,但如果存在,则在右大括号之后应该有一个 typedef 名称。此外,在 C++ 中(与 C 相比),您应该使用枚举类型而不是 int 作为变量(即使编译器很乐意采用 int)。
    • @David:typedef 错误绝对不是标准形式。固定的。我选择不将输入声明为“Choice”,因为这会使输入流运算符“>>”模棱两可。
    • 确定变量的类型,但仍然更喜欢 C++:enum Choice { EASY = 1, MEDIUM = 2, HARD = 3 };,而不是使用未命名枚举的 typedef。
    • 我想这是我从一位老导师那里学到的东西,而且从来没有理由改变。在答案中更新。
    【解决方案3】:

    注意事项:

    你应该总是在命名空间中声明你的枚举,因为枚举不是正确的命名空间,你会很想像使用它们一样使用它们。

    在每个 switch 子句执行结束时总是有一个中断,否则将继续向下直到结束。

    始终在您的开关中包含 default: 大小写。

    为了清楚起见,使用枚举类型的变量来保存枚举值。

    请参阅here,了解有关在 C++ 中正确使用枚举的讨论。

    这就是你想要做的。

    namespace choices
    {
        enum myChoice 
        { 
            EASY = 1 ,
            MEDIUM = 2, 
            HARD = 3  
        };
    }
    
    int main(int c, char** argv)
    {
        choices::myChoice enumVar;
        cin >> enumVar;
        switch (enumVar)
        {
            case choices::EASY:
            {
                // do stuff
                break;
            }
            case choices::MEDIUM:
            {
                // do stuff
                break;
            }
    
            default:
            {
                // is likely to be an error
            }
        };
    
    }
    

    【讨论】:

    • 为了使其工作,您需要为枚举重载 istream operator&gt;&gt;
    • 总体+1,但我不同意always provide a default: 的情况。我了解其意图是触发一个已知错误,以便以后在枚举中添加新的枚举值时可以轻松纠正该错误。我更喜欢实际处理输入以保证用户数据的正确性,而不是提供default 标记,而是让编译器警告 switch 语句,如果有任何值超出所有测试用例。这样你会得到一个更快的错误报告:如果一个值被添加到枚举中,编译器会报错。
    • 另外你可能需要初始化enumVar。如果cin &gt;&gt; enumVar 没有写入值,则此代码会产生未定义的行为,这通常是operator&gt;&gt; 遇到错误时的情况。不过,正如 James 所说,无论如何,您都会为枚举重载运算符,因此您可以编写它以始终分配某些内容,即使发生错误也是如此。
    • 好的 cmets 和建议,这将让我学会在不先编译的情况下发布代码解决方案:P
    • 不同意“总是有一个break...”。有时您想使用“失败”的技巧。并且不同意“始终包含default...”。您可以在 switch 语句之前验证您的输入。
    【解决方案4】:

    您可以使用std::map 将输入映射到您的enum

    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    
    enum level {easy, medium, hard};
    map<string, level> levels;
    
    void register_levels()
    {
        levels["easy"]   = easy;
        levels["medium"] = medium;
        levels["hard"]   = hard;
    }
    
    int main()
    {
        register_levels();
        string input;
        cin >> input;
        switch( levels[input] )
        {
        case easy:
            cout << "easy!"; break;
        case medium:
            cout << "medium!"; break;
        case hard:
            cout << "hard!"; break;
        }
    }
    

    【讨论】:

    • 如果字符串不匹配任何有效选项,这将返回easy
    • 我喜欢这种方法,因为它允许用户输入描述性字符串,而不是整数。一件小事,但我会使用无序映射来处理可能值很少的东西。映射(二叉树)很有趣,因为如果有成百上千个值,映射将比 switch:case 更有效,只需要进行 O(log N) 比较,而不是 N/2。
    • 这是过期的,但在您的枚举中设置的值等于从 1 开始的整数。0 默认为无大小写。所以,枚举级别 = {EASY=1,MEDIUM=2,HARD=3};
    【解决方案5】:

    我在使用带有 switch 案例的枚举时遇到了类似的问题。

    后来,我自己解决了....下面是更正后的代码,也许这可能会有所帮助。

    //Menu Chooser Programme using enum
    #include <iostream>
    
    using namespace std;
    int main()
    {
       enum level{Novice=1, Easy, Medium, Hard};
       level diffLevel = Novice;
       int i;
       cout << "\nEnter a level: ";
       cin >> i;
    
       switch(i)
       {
           case Novice:
               cout << "\nyou picked Novice\n"; break;
    
           case Easy:
               cout << "\nyou picked Easy\n"; break;
    
           case Medium:
               cout << "\nyou picked Medium\n"; break;
    
           case Hard:
               cout << "\nyou picked Hard\n"; break;
    
           default:
               cout << "\nwrong input!!!\n"; break;
       }
       return 0;
    }
    

    【讨论】:

      【解决方案6】:

      您应该记住,如果您从另一个函数访问类范围的枚举,即使它是朋友,您也需要提供带有类名的值:

      class PlayingCard
      {
      private:
        enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES };
        int rank;
        Suit suit;
        friend std::ostream& operator<< (std::ostream& os, const PlayingCard &pc);
      };
      
      std::ostream& operator<< (std::ostream& os, const PlayingCard &pc)
      {
        // Output the rank ...
      
        switch(pc.suit)
        {
          case PlayingCard::HEARTS:
            os << 'h';
            break;
          case PlayingCard::DIAMONDS:
            os << 'd';
            break;
          case PlayingCard::CLUBS:
            os << 'c';
            break;
          case PlayingCard::SPADES:
            os << 's';
            break;
        }
        return os;
      }
      

      注意它是PlayingCard::HEARTS 而不仅仅是HEARTS

      【讨论】:

        【解决方案7】:

        用户的输入将始终以字符串的形式提供给您...如果要将用户的输入从字符串转换为整数,则需要提供代码来执行此操作。如果用户键入一个数字(例如“1”),您可以将字符串传递给 atoi() 以获取与该字符串对应的整数。如果用户键入英文字符串(例如“EASY”),那么您需要检查该字符串(例如使用 strcmp())并根据检查匹配为您的变量分配适当的整数值。一旦你有一个从用户输入字符串派生的整数值,你就可以像往常一样将它传递给 switch() 语句。

        【讨论】:

        • 将输入从字符串转换为整数的代码是int i; cin &gt;&gt; i;。这不是 C,所以没有必要乱搞 C 库。
        【解决方案8】:
        #include <iostream>
        using namespace std;
        
        int main() {
        
            enum level {EASY = 1, NORMAL, HARD};
        
            // Present menu
            int choice;
            cout << "Choose your level:\n\n";
            cout << "1 - Easy.\n";
            cout << "2 - Normal.\n";
            cout << "3 - Hard.\n\n";
            cout << "Choice --> ";
            cin >> choice;
            cout << endl;
        
            switch (choice) {
            case EASY:
                cout << "You chose Easy.\n";
                break;
            case NORMAL:
                cout << "You chose Normal.\n";
                break;
            case HARD:
                cout << "You chose Hard.\n";
                break;
            default:
                cout << "Invalid choice.\n";
            }
        
            return 0;
        }
        

        【讨论】:

          【解决方案9】:

          您可以使用 int 强制转换枚举。

          enum TYPE { one, two, tree };
          
          TYPE u;
          
          u = two;
          
          switch( int( u ) ){
                  case one : 
                  action = do_something ;
                  break;
                  case two:
                  action = do_something_else;
                  break;
          }
          

          【讨论】:

            猜你喜欢
            • 2017-12-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-30
            • 1970-01-01
            相关资源
            最近更新 更多