2013-05-31 6 views
2

Я совершенно новый, и я не знаю, как еще спросить об этом или о том, что даже искать.Навигационное меню консоли

Дело в следующем: я хочу перемещаться по меню с несколькими подменю. В этом примере я просто использую «опции» и «игру», чтобы проиллюстрировать, что я имею в виду. Скажем, у вас есть меню с 3 вариантами.

1 - Начало

2 - Варианты

3 - Выход

варианты Выбор должен принять вас в другое меню. Какой будет выглядеть что-то вроде

1 - Сложность

2 - Sound

3 - назад

В зависимости от того, куда вы идете отсюда, там будет больше подменю, очевидно, , Я пробовал вложенные циклы и всевозможные вещи, но у меня просто недостаточно понимания, чтобы понять, что я делаю неправильно.

Вот то, что я до сих пор:

#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 и т. д. или что?)

ответ

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, чтобы проверить, истинна или ложна переменная (люди склонны использовать логические переменные (bool's) для этого, int, установленный в 1 или 0, сделает то же самое). Это устраняет необходимость в do-while. Рекомендуется прочитать контрольную логику (если/else, while, for loop) и логические операторы (& & - и, || - или,! = - не равно). Логика управления делает ваш код разными, булевы быстро проверяют сценарии да/нет, а логические операторы позволяют проверять несколько элементов в одном выражении 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» и массива в одно и то же время. BTW, пожалуйста, отредактируйте свою запись, чтобы добавить ссылки. Оставьте 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;  
} 

Обратите внимание, что это может быть немного сложным для запуска из. I strong Рекомендую вам прочитать другие ответы, опубликованные людьми. Он должен дать вам несколько подходов к тому, как это сделать, и вы можете перейти от базового до более сложного, изучая каждое изменение.

+0

Это идет по моей голове, но я постараюсь прочитать и посмотреть, что я нахожу. Спасибо =) – fanatical

+0

Отличное начало в меню OOP +, +1. Я нахожусь в поиске хорошего класса меню. Я спросил о SO и закричал и пристыдил к удалению моего вопроса ... –

4

Хорошо, ребята. Спасибо за помощь. В конце концов я закончил. Он работает так, как я хочу, и с помощью примера max_ и комментария Майка Б. Я думаю, что это работает очень хорошо.

Большое спасибо всем =)

#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 за отзыв и обмен результатами - и спасибо за принятие чей-то ответ. –

Смежные вопросы