枚举和开关块哪里出错了

Where am I going wrong with Enums & Switchblocks

我正在学习 C++ 作为我在 Uni 课程的一部分。我在 C++ 方面经验不足,但我已经搜索了几个小时的可能解决方案并测试了数百种代码变体,但我仍然无法正常工作。我相信我对枚举的使用从根本上是错误的——我从来没有让它们按照我的预期工作。对于此任务,我们必须使用枚举和 switch 语句。

#include <iostream>
using namespace std;

enum roomType { Deluxe = 250, Twin = 150, Single = 110};
int temp;
int total;
int input = 1; int yes = 1; int no = 0;

void GetInput()
{
   cin >> input;
   temp = temp*input;
}

int main()
{

   if (input != 0)
   {
      cout << "\nRoom         Price           Code\n------------------------------------\nDeluxe Room " << "\x9C" << "200             D\nTwin Room    " << "\x9C" << "150             T\nSingle               " << "\x9C" << "110             S\n\n";

      cout << "Enter room type:";
      GetInput();
      switch (input) {
         case Deluxe:
            temp = Deluxe;
            break;
         case Twin:
            temp = Twin;
            break;
         case Single:
            temp = Single;
            break;
         default:
            //prevents infinite loop bug
            system("pause");

            cout << "Entry not recognized";
            main();
            break;
      }

      cout << "\nEnter number of rooms:";
      GetInput();
      cout << "\nEnter number of nights:";
      GetInput();
      total = total + temp;
      cout << "\n\x9C" << total << "\n";
      cout << "More rooms? yes/no: ";
      cin >> input;
      main();
   }
   cout << "Discount? yes/no: ";
   GetInput();
   if (input = 1)
   {
      total = ((total / 100) * 75);
      cout << "\n\x9C" << total << "\n";
   }
   cout << "your total is "<<"\x9C" << total;
   system("pause");
   system("cls");
   return 0;
}

如果用户输入房间类型,例如 Deluxe,case 语句总是默认,如果没有 system("pause"); 将继续陷入循环。

出于某种原因,程序似乎忽略了第一个之后的所有 cin >> input;。我知道这是导致循环的原因。我曾尝试将 cin>> 换成 getline(cin,input) 替代方案,但这似乎也不起作用。

刚刚编译了您的代码。你没有为 Delux 做错任何事。枚举值是 250 而你显示的是 200 只是愚蠢的错误。所以当 运行,你输入 200 并且它变为默认值。

关于第二个问题,为什么程序只运行一次,这是因为你想要那样。检查 if (input != 0) 检查输入类型是否为整数值。您可能在命令行中输入 'yes' 而未进行任何错误检查。尝试输入整数值。

PS: 以后请贴出问题代码。

这段代码中你有很多错误;我将枚举结构化为表示开关选择的枚举值,价格在 case 语句中指定。很多时候你打电话给 main();我从来没有在实践中看到过这样做!我不能说它是无效的或非法的,但我从未见过它!我为正确的概念或想法选择了适当的变量类型,例如某物的成本是 float,当您要求用户输入是否有更多房间或是否有折扣时,我使用了bool 类型。您知道我使用的不会为负的值 unsigned。我删除了所有全局变量(通常是不好的做法)。我修复了一些格式以便于阅读。

这是我所做的,我有一些评论来解释我所做的更改;您需要考虑我所做的其他更改。

#include <iostream>
// using namespace std; // Bad Practice

enum RoomType { 
    NONE   = 0,   // NONE For Default Value - No Room Type Selected
    DELUXE, 
    TWIN,    
    SINGLE,

    LAST  // MUST BE LAST!
};

/*void GetInput() {  // Function Not Really Required In This Simple Application
    cin >> input;
    temp = temp*input;
}*/

int main() {
    while ( true ) {
        float totalCost = 0; // Renamed Variable For Better Readability
        int input = 0; // Initialized To 0, We Do Not Know What The User Will Choice
        std::cout <<  std::endl << "Room        Price       Code" << std::endl 
                  << "------------------------------------" << std::endl 
                  << "Deluxe Room " << "\x9C" << "250       D" << std::endl 
                  << "Twin Room   " << "\x9C" << "150       T" << std::endl 
                  << "Single      " << "\x9C" << "110       S" << std::endl << std::endl;

        std::cout << "Please Make A Selection:" << std::endl
                  << "1 - Deluxe" << std::endl
                  << "2 - Twin"   << std::endl
                  << "3 - Single" << std::endl << std::endl;

        std::cin >> input;

        // You Never Declare Variable Type Of RoomType
        RoomType type = static_cast<RoomType>( input ); // Cast input to RoomType 
        float costOfRoom = 0.0f;

        switch (type) {
            case NONE: {
                costOfRoom = 0.0f;
                break;
            }
            case DELUXE: {
                    costOfRoom = 250.0f;
                break;
            }
            case TWIN: {
                costOfRoom = 150.0f;
                break;
            }
            case SINGLE: {
                costOfRoom = 110.0f;
                break;
            }
            default: {
                    std::cout << "Entry not recognized";
                //main(); wrong
                break;
            }
        } // Switch


        unsigned numRooms = 0;
        unsigned numNights = 0;

        std::cout << std::endl << "Enter number of rooms:";
        std::cin >> numRooms;

        std::cout << std::endl << "Enter number of nights:";
        std::cin >> numNights;

        totalCost = costOfRoom * numNights * numRooms;

        std::cout << "\n\x9C" << totalCost << "\n";

        bool moreRooms = false;
        bool hasDiscount = false;

        input = 0;
        std::cout << "More rooms? 1 for yes - 0 for no: ";
        std::cin >> moreRooms;
        if ( moreRooms ) {
            std::cout << "Please Enter Number Of Rooms. ";
            std::cin >> input;
            totalCost += (costOfRoom * numNights * input);
        }

        // main(); // Wrong!
        std::cout << "Discount? 1 for yes - 0 for no: ";
        std::cin >> hasDiscount;
        if ( hasDiscount ) {
            totalCost = ((totalCost / 100) * 75);
            std::cout << std::endl << "\x9C" << totalCost << std::endl;
        }
        std::cout << "Your total is " <<"\x9C" << totalCost << std::endl;

        bool runAgain = false;
        std::cout << std::endl << "Would you like to contine? 1 - yes - 0 for no:";
        std::cin >> runAgain;

        if ( !runAgain ) {
            break;
        }
    } // while

    system("pause");
    system("cls");
    return 0;
} // main

注意:这并没有直接回答用户的问题;我已经在上面做到了。这是一个基于用户回复之一的示例,用于演示枚举和枚举类型的使用,以便他们能够更轻松、更好地理解它们。

这里有两个函数原型,它们可以做同样的事情,一个使用枚举,而另一个不使用。

enum ProductType {
    HARDWARE = 1,
    TOOLS,
    APPLIANCES,
    FURNITURE,
    LAWN_AND_GARDEN,
    PAINT
};

// This Version Doesn't Use An Enumerated Value And Takes In An Unsigned Int
float calculateProductTotalCost( unsigned int productType, float costOfProduct, unsigned int numberOfItems );

float calculateProductTotalCost( ProductType type, float costOfProduct, unsigned int numberOfItems );


someOtherFunction() { // Could be main()

    // This function has a magic number to represent the product type
    calcluateProductTotalCost( 3, 1499.99f, 2 );

    // This version uses the enumeration with the scope resolution operator
    // to allow the calling of this function to be easier to read.
    calculateProductTotalCost( ProductType::PAINT, 23.50f, 150 );

    // Although I did not show any implementation for these functions
    // since that is irrelevant, the importance of the two is that in
    // practice these methods would be the same and perform the same
    // exact calculation and operation. It is just more readable for
    // another human to see your code when they have to work on it
    // sometime in the future and you are not there to explain what you
    // did and why you did it. It can even be a help for yourself if
    // you go back to code that you have written that you have not seen
    // in a few months or years. Then just by reading the Wording
    // of the Enumeration you know that this value represents this specific
    // object.
}

这是另一个例子

SoundSource {
    CLAP = 1,
    BANG,
    GUN_SHOT,
    THUNDER_BOLT,
    LAUGHTER,
    SCREAM,
};


bool playSound( unsigned int, bool bLoop );
bool playSound( SoundSource, bool bLoop );

someFunction() {
    // Which group of function calls looks better and is easier to understand; Group A or Group B?

    // Group A
    playSound( 6, false );
    playSound( 4, true );
    playSound( 3, false );

    // Group B
    playSound( SoundSource::THUNDER_BOLT, true );
    playSound( SoundSource::SCREAM, false );
    playSound( SoundSource::LAUGH, true );    
}

希望本文能帮助您理解枚举的用途;它们适用于一些不同的事情,适用于 switch case 语句,并且允许通常由 ID 值(通常是无符号的)传递的不同数据类型也由作为枚举值的单词表示。如果您注意到将枚举中的所有值命名为 ALL_CAPS 是一种很好的做法,请用下划线分隔每个单词;但这也只是偏好,但大多数人在看到全部大写时都会将其识别为枚举。