2013-05-31 268 views
2

我是全新的,我不知道还有甚么要问这个或甚至要搜索什么。导航控制台菜单

情况是这样的:我想通过一个菜单浏览几个子菜单。在这个例子中,我将使用“选项”和“游戏”来说明我的意思。假设你有一个包含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等?或什么?)

回答

1

这个怎么样(不知道如果它编译虽然):

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

这大致产生了我的问题。 除了回到主菜单外,你可以正确地工作。这只是不会发生。 – fanatical

+0

好的,我已经测试了我的代码,并对选择变量做了一些小改进,它应该在do-while循环之外声明(我相应地更新了我的帖子中的代码)。但除了这个小缺陷之外,它对我来说非常合适。 –

1

看看你正在尝试做什么,我会改变你如何确保用户仍然希望首先玩游戏。看看使用while循环来检查一个变量是真还是假(人们倾向于使用布尔变量(布尔的)为此,int设置为1或0会做同样的)。这消除了对“尽快”的需求。建议阅读控制逻辑(if/else,for循环)和逻辑运算符(& & - 和|| - 或!! - 不等于)。控制逻辑使你的代码做不同的事情,布尔变得快速检查是/否场景,逻辑运算符允许你在一个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.. 
     } 

    } 

}

这是我的第一个合适的回答,所有可怕的批评是很好收到。

+1

你说*使用另一个变量(int或任何适合你)*'enum'是为这个伟大的。它们同时是'#define'和一个数组的完美结合。顺便说一句,请编辑您的帖子以添加链接。离开http://或根据需要更改为(dot)(com)以发布它们。我特别讨厌stackexchange限制人们帮助别人。 –

1

我建议你改变一些东西在这里。你熟悉面向对象的设计吗?如果不是的话,强烈建议你阅读一下,如果你想用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;  
} 

注意,这可能是开始了一个有点复杂。我强烈建议您阅读人们已发布的其他答案。它应该给你一些关于如何去做的方法,你可以从基础到更复杂的过程,检查每一个变化。

+0

这是在我头上的方式,但我会尝试阅读,看看我找到了什么。谢谢=) – fanatical

+0

OOP +菜单很棒的开始,+1。我正在努力寻找一个好的菜单课。我询问了这个问题,并大声疾呼,删除了我的问题... –

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; 

} 
+0

+1提供反馈并分享结果 - 并感谢您接受某人的回答。 –