Для меню я рекомендую использовать таблицы состояний (программное обеспечение, управляемое данными):
// Define short hand for function pointer
typedef void (*Menu_Processing_Function_Ptr)();
struct Menu_Item
{
unsigned int number;
const char * text;
Menu_Processing_Function_Ptr p_processing_function;
};
Учитывая приведенную выше структуру пунктов меню, вы можете создать общий механизм , который обрабатывает {любое} меню. Меню будет массивом Menu_Item
.
void Menu_Engine(Menu_Item * p_menu, unsigned int item_quantity)
{
// Display the menu
for (unsigned int i = 0; i < item_quantity; ++i)
{
std::cout << p_menu[i].number
<< ". "
<< p_menu[i].text
<< "\n";
}
std::cout << "Enter selection: ";
unsigned int selection;
std::cin >> selection;
for (unsigned int i = 0; i < item_quantity; ++i)
{
if (selection == p_menu[i].number)
{
// Execute the processing function for the selection.
(p_menu[i].p_processing_function)();
break;
}
}
if (i >= item_quantity)
{
std::cout << "invalid selection\n";
}
}
Затем вы можете определить меню как:
// Forward declarations
void Process_Selection_1();
void Process_Selection_2();
void Process_Selection_3();
Menu_Item first_menu[] =
{
{1, "First Selection", Process_Selection_1},
{2, "Second Selection", Process_Selection_2},
{3, "Third Selection", Process_Selection_3},
};
static const unsigned int menu_size =
sizeof(first_menu) / sizeof(first_menu[0]);
Пример использования:
int main()
{
// Process the menu
Menu_Engine(&first_menu[0]);
// Pause.
std::cout << "Paused. Press ENTER to continue.";
std::cin.ignore(1000000, '\n');
return 0;
}
Этот шаблон позволяет изменять меню без необходимости повторного тестирования или изменения кода ( engine ). Добавление выделения или изменение выделения не влияет на двигатель.
Это позволяет помещать меню в постоянную память.
Вам понадобится только один движок для обработки нескольких меню.
Редактировать 1: std :: map
Другая возможность состоит в использовании ассоциативного массива, сопоставляющего номер выбора с атрибутами выбора:
struct Menu_Item_Attributes
{
const char * text;
Menu_Processing_Function_Ptr p_processing_function;
};
typedef std::map<unsigned int, Menu_Item_Attributes> Menu_Item_Container;
Ваша обработка ввода будет:
unsigned int selection;
std::cout << "Enter selection: ";
std::cin >> selection;
try
{
Menu_Item_Attributes attributes = menu.at(selection);
(attributes.p_processing_function)();
}
catch (std::out_of_range& e)
{
std::cout << "Invalid selection";
}
Напоминание о том, что std::map
не может быть сохранен в постоянной памяти и должен быть инициализирован во время выполнения.