создавать меню в командной строке - PullRequest
5 голосов
/ 14 января 2011

Как создать меню в программе командной строки? Я пробовал такие вещи, как:

cin >> input;
switch (input) {
  case (1):
    // do stuff
  case (2):
    // ...
}

но тогда у меня возникла проблема с подменю, и я вернулся к тому же меню и т. Д. Первая программа, которую я написал (кроме упражнений), которая пыталась использовать идею switch для меню, имела goto операторов, потому что альтернативой были кучи (в то время) сложных циклов.

Ответы [ 3 ]

9 голосов
/ 14 января 2011

Если бы я попытался сосчитать, каким образом можно создать меню 1,2,3, мы оба были бы мертвы, прежде чем я повторил бы половину из них. Но вот один из способов, с помощью которого вы можете попытаться начать работу (не проверенный, вам может понадобиться очистить пару вещей):

struct menu_item
{
  virtual ~menu_item() {}
  virtual std::string item_text() const = 0;
  virtual void go() = 0;
};

struct print_hello_item
{
  std::string item_text() const { return "display greeting"; }
  void go() { std::cout << "Hello there, Mr. User."; }
};

struct kill_everyone_item
{
  std::string item_text() const { return "Go on murderous rampage"; }
  void go() { for(;;) kill_the_world(); }
};

struct menu_menu_item
{
  menu_menu_item(std::string const& text) : text_(text), items() {}
  void add_item(std::unique_ptr<menu_item> item) { items.push_back(std::move(item)); }
  void go()
  {
    std::cout << "Choose: \n";
    std::for_each(items.begin(), items.end(), [](std::unique_ptr<menu_item> const& item)
    {
      std::cout << "\t" << item->item_text() << "\n";
    });
    std::cout << "\n\n\tYour choice: ";
    int choice = get_number_from_console();
    if (items.size() > choice) items[choice]->go();
  }
  std::string item_text() const { return text_; }

private:
  std::string text_;
  std::vector<std::unique_ptr<menu_item> > items;
};

int main()
{
  menu_menu_item top_item;
  top_item.add(std::unique_ptr<menu_item>(new print_hello_item));
  top_item.add(std::unique_ptr<menu_item>(new kill_everyone_item));

  top_item.go();
}

Как упражнение, как я могу определить пункты меню следующим образом:

top_level.add()
  ( "Drive off a cliff", &die_function )
  ( "Destroy the world", &global_thermal_nuclear_war )
  ( "Deeper", submenu()
                ( "Hey, check this shit out!", &gawk ))
;

Это может быть сделано с вышеупомянутой структурой в качестве отправной точки.

В этом разница между ОО-дизайном и тем, что можно назвать «процедурным». Я создал абстракцию за тем, что значит быть выбором меню (которое может быть другим меню), которое можно расширять в различных направлениях. Я создаю нужные мне расширения, соединяю их и говорю, что нужно делать. Хороший ОО-дизайн просто так ... основная часть вашей программы состоит из того, чтобы собрать воедино все и заставить его работать.

Ключевым моментом, который нужно извлечь из этого, является не обязательно делать это так, как я это делал, а думать об этом по-другому. Если вы сможете понять суть приведенного выше кода, то увидите, что вы можете добавлять новые элементы, с новыми меню, на произвольную глубину, без необходимости иметь дело с чрезмерно сложным кодом, вызываемым стилем переключения.

2 голосов
/ 14 января 2011

Вы можете интегрировать подменю в вашем меню с помощью вашего метода:

cin >> input;
switch (input) {
  case (1): 
    cin >> input;
    switch (input) {
       case (1): //do stuff
       case (2): //do stuff
    }
    break;
  case (2):
    break;
}

Это то, что вы ищете?В противном случае: Что вы хотите точно решить?

Редактировать: Так что вам нужен дополнительный цикл в ваших подменю с условием прерывания?

do{
    cin >> input;
    switch (input) {
      case (1): 
        do{
          cin >> input;
          switch (input) {
            case (1): //do stuff
            case (2): //do stuff
          }
        }while(input != 3);
        break;
      case (2):
        break;
    }
  }while(true);
1 голос
/ 15 марта 2012

Я только что задал похожий вопрос на Библиотеки для отображения меню в текстовом режиме? - похоже, ncurses значительно упростит части отображения меню.

...