作为刚入计算机以及相关专业的学生,你是否经常遇到一些很让人无语的作业叫你写一个cmd黑窗口的菜单界面?又或者有些作业太简单以至于写一个Qt界面有点杀鸡用牛刀?我们确实可以每次作业都写一堆的if-else或者switch语句,不过这样调来调去很烦,所以就有了这个simpleMenu,不是Qt不是ImGUI不是openGL就只有cmd黑窗口的超级简单的菜单simpleMenu类,也没有任何索引归纳功能,就只能用来表示菜单,这玩意写了说白了就是应付作业用的。
不多废话直接上代码:
#include <iostream>
#include <functional>
#include <vector>
using std::string, std::function, std::cout, std::endl, std::cin;
class simpleMenu {
struct choise {
string choiseName;
function<void()> choiseFunction;
choise(string choiseName, const function<void()> &choiseFunction)
: choiseName(std::move(choiseName)), choiseFunction(choiseFunction) {
}
};
string title;
std::vector<choise> choises;
function<void()> startFun, endFun;
void printMenu() {
cout << title << endl;
int x = 1;
for (auto &it: choises)
cout << x++ << "-<" << it.choiseName << ">" << endl;
cout << "0-<exit>" << endl;
}
public:
explicit simpleMenu(string title = "Menu", const function<void()> &startFun = nullptr,
const function<void()> &endFun = nullptr)
: title(std::move(title)), startFun(startFun), endFun(endFun) {
}
void runMenu() {
while (true) {
if (startFun) startFun();
printMenu();
cout << "please input your choise: ";
int num;
cin >> num;
if (num == 0) return;
if (num >= 1 && num <= choises.size()) {
system("cls");
choises[num - 1].choiseFunction();
} else
cout << "Invalid choise" << endl;
if (endFun) endFun();
system("pause");
system("cls");
}
}
void addChoise(const string &choiseName, const function<void()> &choiseFunction) {
choises.emplace_back(choiseName, choiseFunction);
}
};
然后来点示例代码:
#include "simpleMenu.cpp"
void stratFun() {
cout << "StartFun working!" << endl;
}
void endFun() {
cout << "EndFun working!" << endl;
}
void choiseOneFun() {
cout << "choise one" << endl;
}
void choiseTwoFun(int a, int b) {
cout << a + b << endl;
}
class choiseFour {
public:
choiseFour() = default;
void Fun() {
cout << "choise four" << endl;
}
};
void MenuSample() {
simpleMenu menu("Main Menu", stratFun, endFun);
menu.addChoise("choise one", choiseOneFun);
menu.addChoise("choise two", []() { choiseTwoFun(1, 2); });
menu.addChoise("choise three", []() { cout << "choise three" << endl; });
choiseFour cf;
menu.addChoise("choise four", [&]() { cf.Fun(); });
menu.runMenu();
}
int main() {
MenuSample();
return 0;
}
输出:
然后随便选一个4输入进去:
基本的逻辑在MenuSample()中基本都能体现出来了,即使用构造函数设定标题(title)、开菜单前的操作函数(startFun)、操作结束后的操作函数(endFun),这里后两个可以省略默认就不输出了。
然后使用addChoise添加选项,选项会自动编号,默认最后一个选项是0-<exit>,最后调用runMenu就可以跑这个菜单了。
注意添加选项的choiseFunction是一个没有参数、返回值为void空的函数,如果你的选项是一个有参数的,就跟示例代码中一样使用lambda表达式封装一下,如果调用到是当前函数范围下(示例代码中是MenuSample这个函数中的choiseFour cf)的类或者其他lambda表达式函数,那么不要忘了[&](){}中间的&捕捉,不然会报错未定义某些值。
当然菜单是可以嵌套的,subMenu()里面新建一组menu,然后在mianMenu选项添加中调用subMenu()就行了。