在命令行中创建菜单

时间:2011-01-14 04:44:30

标签: c++ menu console

如何在命令行程序中创建菜单?我尝试了类似的东西:

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

然后我遇到了子菜单的问题,并回到了相同的菜单等。我写的第一个程序(除了练习)试图使用switch的想法进行菜单有goto语句,因为替代方案是(当时)复杂的循环。

3 个答案:

答案 0 :(得分:9)

如果我试图计算一个人创建1,2,3菜单的方式,那么在我迭代其中的1/2之前我们都已经死了。但是这里有一种方法可以让你开始尝试(未经测试,你可能需要清理几件事):

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 ))
;

可以用上述框架作为起点。

这是OO设计与可能被称为“程序”之间的区别。我创建了一个抽象背后的菜单选择(可以是另一个菜单),可以在各个方向扩展。我创建了我需要的扩展,将它们组合在一起,然后告诉它。好的OO设计就是这样......你的程序的主要部分包括把东西放在一起并告诉它。

从中获取的关键不一定是按照我刚才的方式去做,而是以不同的方式思考它。如果您可以获得上述代码的要点,那么您将看到可以使用新菜单将新项目添加到任意深度,而无需处理切换样式导致的过于复杂的代码。

答案 1 :(得分:2)

您可以使用您的方法将菜单中的子菜单集成:

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);

答案 2 :(得分:1)

我刚刚在Libraries for displaying a text-mode menu?问了一个类似的问题 - 看起来ncurses会大大简化菜单显示部分。