【问题标题】:Where am I going wrong with Enums & Switchblocks枚举和开关块哪里出错了
【发布时间】:2015-10-28 02:20:31
【问题描述】:

我正在学习 C++,这是我在 Uni 课程的一部分。我对 c++ 的经验并不丰富,但我已经搜索了几个小时的可能解决方案并测试了数百种代码变体,但我仍然无法使其正常工作。我相信我对 Enums 的使用从根本上是错误的——我从来没有让它们按我的意图工作。对于这个任务,我们必须使用 Enums 和 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 &gt;&gt; input;。我知道这是导致循环的原因。我曾尝试将cin&gt;&gt; 换成getline(cin,input)alternative,但这似乎也不起作用。

【问题讨论】:

  • 复制粘贴代码到这里。 (您可能需要使用全选 -> ctrl+K 格式化代码)
  • 我假设您设置为枚举的值是房间成本,而用户选择选择特定房间类型的值不在协议中。您永远不会声明枚举的变量类型,甚至在代码中使用它。在下面查看我的答案,以查看使用枚举作为选择类型的工作应用程序。价格在案例陈述中确定。此外,还会要求用户做出与枚举类型相同的选择。

标签: c++ visual-c++ enums switch-statement


【解决方案1】:

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

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

PS:以后请自行粘贴相关代码。

【讨论】:

  • 是否可以逐字输入“Deluxe”并让程序将其识别为 250 - 这是我试图做的,但它似乎不像在 int 上那样在 enum 上工作。
  • @Anroca 是的。枚举是整数类型,这意味着它们只能是从 0 + 开始的 + 整数。我将向您展示一个不使用枚举的函数声明,而不是使用低于我之前答案的函数声明。
【解决方案2】:

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

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

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,用下划线分隔每个单词;但这也只是偏好,但大多数人在看到所有大写字母时都会将其识别为枚举。

【讨论】:

  • 也许晚了 3 年多,但我想这个答案会很有帮助。经过反思,我对 Enums 的使用从根本上是错误的。您的第二个示例很好地展示了如何使用它们 - 并且比我们当时使用的材料要好得多。
【解决方案3】:

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

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

#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

【讨论】:

  • 注意:当用户希望输入数字值而不是字符或字符串值时,这里没有错误检查。当用户被要求输入 1,2 或 3 值时,没有什么能阻止用户输入“ABCdef”。我没有将其合并,并留给用户使用此已发布问题的原始代码。
  • 唯一一次看到递归main()是著名的圣诞节12天混淆程序..
猜你喜欢
  • 1970-01-01
  • 2021-04-27
  • 2014-05-12
  • 2022-11-11
  • 1970-01-01
  • 2023-03-24
  • 2015-03-13
  • 2013-05-26
  • 1970-01-01
相关资源
最近更新 更多