5

我是全新的,我不知道该怎么问这个或什至要搜索什么。

情况是这样的:我想浏览一个带有多个子菜单的菜单。在此示例中,我将仅使用“选项”和“游戏”来说明我的意思。假设您有一个包含 3 个选项的菜单。

1 - 开始

2 - 选项

3 - 退出

选择选项应该带您进入另一个菜单。然后看起来像

1 - 难度

2 - 声音

3 - 背部

根据你从这里去的地方,显然会有更多的子菜单。我试过嵌套 do-while 循环和各种各样的东西,但我只是没有足够的理解来知道我做错了什么。

这是我到目前为止所拥有的:

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
  int choice;

    do{
    cout << "Main Menu\n";
    cout << "Please make your selection\n";
    cout << "1 - Start game\n";
    cout << "2 - Options\n";
    cout << "3 - Quit\n";
    cout << "Selection: ";
    cin >> choice;

         switch(choice) {
           case 1:
             cout << "Pew pew!\n";
             break;
           case 2:
             cout <<"????\n";
             break;
           case 3:
             cout << "Goodbye!";
             break;
           default:
             cout << "Main Menu\n";
             cout << "Please make your selection\n";
             cout << "1 - Start game\n";
             cout << "2 - Options\n";
             cout << "3 - Quit\n";
             cout << "Selection: ";
             cin >> choice;    
         }
      } while(choice !=3);                            
    system("PAUSE");
    return EXIT_SUCCESS;
}

这就像一个普通的菜单。但我不知道从这里去哪里。我查阅了一些书,但发现任何与此无关的东西都是完全随机的。任何帮助或示例将不胜感激。

嵌套大量循环所发生的事情只是使所有循环每次都同时执行。我如何防止这种情况发生?做出更多选择?(choice1-2-3 等?还是什么?)

4

4 回答 4

5

好,朋友们。感谢所有的帮助。这就是我最终得到的结果。它按照我的意愿运行,并且通过 max_ 的示例和 Mike B 的评论,我认为这非常有效。

非常感谢大家=)

#include <iostream>
#include <cstdlib>


using namespace std;

void menu();
void mainMenu();
void optionsMenu();
void options();
int choice1 = 0;
int choice2 = 3;

int main(int argc, char** argv) {



    menu();



    return 0;
}


void menu(){

        do {
        choice2 = 0;
        mainMenu();

        switch(choice1) {

            case 1:
                cout << "Pew pew!\n";
                break;

            case 2:
                options();
                break;

            case 3:
                break;

        }

    } while(choice1 != 3);


}

void options(void) {

    do {
        optionsMenu();

        switch(choice2){

            case 1:
                cout << "So difficult!\n";
                break;

            case 2: 
                cout << "Beep!\n";
                break;

            case 3:
                break;

            default: 
                break;

        }

    } while(choice2 != 3);


}




void mainMenu(void) {



    cout << "Main Menu\n";
    cout << "1 - Start game\n";
    cout << "2 - Options\n";
    cout << "3 - Quit\n";
    cout << "Please choose: ";
            cin >> choice1;

}

void optionsMenu(void) {



    cout << "Options Menu\n";
    cout << "1 - Difficulty\n";
    cout << "2 - Sound";
    cout << "3 - Back\n";
    cout << "Please choose: ";
            cin >> choice2;

}
于 2013-06-02T17:33:58.187 回答
4

这个怎么样(不知道它是否可以编译):

     #include <cstdlib>
     #include <iostream>

     using namespace std;

     int GetInput()
     {
         int choice;    
        cin >> choice;
        return choice;
     }

     void DisplayMainMenu()
     {
     cout << "Main Menu\n";
         cout << "Please make your selection\n";
         cout << "1 - Start game\n";
         cout << "2 - Options\n";
         cout << "3 - Quit\n";
         cout << "Selection: ";
     }

     void DisplayOptionsMenu()
     {
         cout << "Options Menu\n";
         cout << "Please make your selection\n";
         cout << "1 - Difficulty\n";
         cout << "2 - Sound\n";
         cout << "3 - Back\n";
         cout << "Selection: ";
     }

     void Options()
     {
        int choice = 0;
        do
        {
            system("cls");
            DisplayOptionsMenu();
            choice = GetInput();
            switch(choice)
            {
                case 1:
                    cout << "difficulty stuff";
                    break;
                case 2:
                    cout << "sound stuff";
                    break;
                case 3:
                    break;
                default:
                    break;
            }
        } while(choice!=3);
     }

     int main(int argc, char *argv[])
     {
         int choice = 0;

         do
         {
            system("cls");
            DisplayMainMenu();
            choice = GetInput();
            switch(choice) {
                    case 1:
                            cout << "Pew pew!\n";
                            break;
                    case 2: 
                            Options();
                            break;
                    case 3: 
                            cout << "Goodbye!";
                            break;

                    default: 
                            break;
                   }
           } while(choice!=3);
         system("PAUSE");
         return EXIT_SUCCESS;
     }
于 2013-05-31T08:55:32.937 回答
4

我建议您在这里更改一些内容。你熟悉面向对象的设计吗?如果没有,如果您想用 C++ 编写代码(或者只是一般地编写代码,因为它是许多编程语言的一个非常重要的方面),强烈建议您阅读相关内容

考虑将每个菜单和子菜单视为单独的对象。每次进入循环时,使用对象指针调用打印当前菜单文本的方法。

然后,像往常一样接受用户的输入,并更改您现在正在使用的菜单对象。

这可能不是制作控制台菜单的最理想方式,但它会为您提供面向对象编程如何工作的非常坚实的基础。

我附上了一个例子:

#include <iostream>
#include <string>

class BaseMenu
{
public:
    BaseMenu() { m_MenuText = "This shouldn't ever be shown!"; } // This is the constructor - we use it to set class-specific information. Here, each menu object has its own menu text.
    virtual ~BaseMenu() { } // This is the virtual destructor. It must be made virtual, else you get memory leaks - it's not a quick explaination, I recommend you read up on it
    virtual BaseMenu *getNextMenu(int iChoice, bool& iIsQuitOptionSelected) = 0; // This is a 'pure virtual method', as shown by the "= 0". It means it doesn't do anything. It's used to set up the framework
    virtual void printText() // This is made virtual, but doesn't *have* to be redefined. In the current code I have written, it is not redefined as we store the menu text as a string in the object
    {
        std::cout << m_MenuText << std::endl;
    }

protected:
    std::string m_MenuText; // This string will be shared by all children (i.e. derived) classes
};

class FirstMenu : public BaseMenu // We're saying that this FirstMenu class is a type of BaseMenu
{
    FirstMenu()
    {
        m_MenuText = "Main Menu\n"                         // What we are doing here is setting up the string to be displayed later
                    + "Please make your selection\n"       // What we are doing here is setting up the string to be displayed later
                    + "1 - Start game\n"                   // What we are doing here is setting up the string to be displayed later
                    + "2 - Options\n"                      // What we are doing here is setting up the string to be displayed later
                    + "3 - Quit\n"                         // What we are doing here is setting up the string to be displayed later
                    + "Selection: ";                       // What we are doing here is setting up the string to be displayed later
    }

    BaseMenu *getNextMenu(int choice, bool& iIsQuitOptionSelected) // This is us actually defining the pure virtual method above
    {
        BaseMenu *aNewMenu = 0; // We're setting up the pointer here, but makin sure it's null (0)

        switch (choice) // Notice - I have only done "options". You would obviously need to do this for all of your menus
        {
            case 2:
            {
                aNewMenu = new SecondMenu; // We're creating our new menu object here, and will send it back to the main function below
            }

            case 3:
            {
                // Ah, they selected quit! Update the bool we got as input
                iIsQuitOptionSelected = true;
            }

            default:
            {
                // Do nothing - we won't change the menu
            }

        }

        return aNewMenu; // Sending it back to the main function
    }

};

class SecondMenu : public BaseMenu
{
    SecondMenu()
    {
        m_MenuText = "OptionsMenu\n"
                    + "Please make your selection\n"
                    + "1 - ????"
                    + "2 - dafuq?";
    }

    BaseMenu *getNextMenu(int choice, bool& iIsQuitOptionSelected) // This is us actually defining the pure virtual method above
    {
        BaseMenu *aNewMenu = 0; // We're setting up the pointer here, but makin sure it's null (0)

        switch (choice) // Notice - I have only done options. You would obviously need to do this for all of your menus
        {
            case 1:
            {
                aNewMenu = new FirstMenu; // We're creating our new menu object here, and will send it back to the main function below
            }
            break;
            case 2:
            {
                aNewMenu = new FirstMenu; // We're creating our new menu object here, and will send it back to the main function below
            }
            break;

            default:
            {
                // Do nothing - we won't change the menu
            }

        }

        return aNewMenu; // Sending it back to the main function
    }
};

int main (int argc, char **argv)
{
    BaseMenu* aCurrentMenu = new FirstMenu; // We have a pointer to our menu. We're using a pointer so we can change the menu seamlessly.
    bool isQuitOptionSelected = false;
    while (!isQuitOptionSelected) // We're saying that, as long as the quit option wasn't selected, we keep running
    {
        aCurrentMenu.printText(); // This will call the method of whichever MenuObject we're using, and print the text we want to display

        int choice = 0; // Always initialise variables, unless you're 100% sure you don't want to.
        cin >> choice;

        BaseMenu* aNewMenuPointer = aBaseMenu.getNextMenu(choice, isQuitOptionSelected); // This will return a new object, of the type of the new menu we want. Also checks if quit was selected

        if (aNewMenuPointer) // This is why we set the pointer to 0 when we were creating the new menu - if it's 0, we didn't create a new menu, so we will stick with the old one
        {
            delete aCurrentMenu; // We're doing this to clean up the old menu, and not leak memory.
            aCurrentMenu = aNewMenuPointer; // We're updating the 'current menu' with the new menu we just created
        }
    }

    return true;    
}

请注意,这对于开始可能有点复杂。我强烈建议您阅读人们发布的其他答案。它应该为您提供一些如何做到这一点的方法,并且您可以从基本到更复杂,检查每个更改。

于 2013-05-31T09:06:34.790 回答
1

看看你想要做什么,我会改变你如何确保用户仍然想先玩游戏。看看使用 while 循环来检查变量是真还是假(人们倾向于为此使用布尔变量(bool's),将 int 设置为 1 或 0 也会这样做)。这消除了do-while的需要。建议阅读控制逻辑(if/else、while、for 循环)和逻辑运算符(&& - 和、|| - 或、!= - 不等于)。控制逻辑使您的代码做不同的事情,布尔值可以快速检查是/否场景,逻辑运算符允许您在一个 if 语句中检查多个项目。一些阅读:循环

编辑:有更多阅读材料的链接,没有代表发布它们。

其次,使用另一个变量(int 或任何适合您的变量)来跟踪您所在的屏幕。基于此选择,显示不同的选项,但仍输入 1、2、3 以决定下一步操作。

在一些可怕的伪代码中,我倾向于:

main()
{
   int choice
   int screen = 1
   bool running = true

   while(running) {
       //Screen 1, Main menu
       if(screen == 1) {
       cout << stuff
       cout << stuff
       cout << option 1
       cout << option 2
       cout << option 3
       cout << selection:
       cin >> choice
       }
       else if(screen == 2){
       //options screen here

       }
       else {
       //default/error message
       }

       //add some choice logic here
       if(screen == 1 && choice == 3){
           //being on screen one AND choice three is quit
           running = false;
       }
       else if(screen == 1 && choice == 2){
           //etc..
       }

  }

}

这是我的第一个正确答案,所有可怕的批评都受到好评。

于 2013-05-31T08:49:59.367 回答