如何在命令行程序中創建菜單?我試過的東西,如:在命令行中創建菜單
cin >> input;
switch (input) {
case (1):
// do stuff
case (2):
// ...
}
但當時我已經有子菜單的問題,並要回同樣的菜單,等等。第一個程序我寫的(除了練習)那些試圖使用switch
想法的菜單有goto
陳述,因爲替代是堆(當時)複雜的循環。
如何在命令行程序中創建菜單?我試過的東西,如:在命令行中創建菜單
cin >> input;
switch (input) {
case (1):
// do stuff
case (2):
// ...
}
但當時我已經有子菜單的問題,並要回同樣的菜單,等等。第一個程序我寫的(除了練習)那些試圖使用switch
想法的菜單有goto
陳述,因爲替代是堆(當時)複雜的循環。
如果我試圖計算創建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();
}
作爲exercize,我怎麼可能會定義像這樣的菜單項:
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設計就是這樣......你的程序的主要部分是組裝東西並告訴它去。
從中取得的關鍵不一定是按照我剛剛做的方式來做,而是以不同的方式來思考它。如果你能得到上面代碼的要點,那麼你會發現你可以用新的菜單將新的項目添加到任意深度,而不必處理交換風格導致的那種過於複雜的代碼。
您可以在菜單中有你的方法整合子菜單:
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);
我剛剛在Libraries for displaying a text-mode menu?處問過類似的問題 - 看起來ncurses會大大簡化菜單顯示部分。
在你給出的菜單的上下文中,我希望一旦用戶完成一個動作(例如第一個做的東西,它會返回到子菜單,並且會有一個選項返回到第一個菜單,這是否有意義? – 2011-01-14 04:56:06
啊,好的 - 我看到了......我已經添加了這種情況下的源代碼 – Constantin 2011-01-14 05:08:24
這似乎會起作用 – 2011-01-14 05:25:16