如何在命令行程序中创建菜单?我尝试了类似的东西:
cin >> input;
switch (input) {
case (1):
// do stuff
case (2):
// ...
}
然后我遇到了子菜单的问题,并回到了相同的菜单等。我写的第一个程序(除了练习)试图使用switch
的想法进行菜单有goto
语句,因为替代方案是(当时)复杂的循环。
答案 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会大大简化菜单显示部分。