浏览控制台菜单

时间:2013-05-31 08:26:50

标签: c++ menu console do-while

我是全新的,我不知道如何问这个或者甚至搜索什么。

案例是这样的:我想浏览带有几个子菜单的菜单。在这个例子中,我将只使用“选项”和“游戏”来说明我的意思。假设您有一个包含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;
}

其功能类似于常规菜单。但我不知道从哪里开始。我查阅过一些书籍,但发现与此有关的任何东西都是随机的。任何帮助或示例将不胜感激。

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

4 个答案:

答案 0 :(得分:4)

好的伙计们。谢谢你的帮助。这就是我最终得到的结果。 它按照我的要求运行,并且通过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;

}

答案 1 :(得分:2)

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

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

然后,正常地从用户那里获取输入,并更改您现在正在使用的菜单对象。

这可能不是执行控制台菜单的最理想方式,但它将为您提供一个非常强大的基础,以确定面向对象的编程是如何工作的。

我附上了一个例子:

#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;    
}

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

答案 2 :(得分:1)

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

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

其次,使用另一个变量(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..
       }

  }

}

这是我的第一个正确答案,所有可怕的批评都得到了很好的回应。

答案 3 :(得分:1)

这个怎么样(dunno,如果它编译虽然):

     #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;
     }