I am creating a program that has a main menu that when you choose an option lets say 1, will take you to a sub menu which allows you to choose another option, lets say 1 again.
I am not able to figure out how to connect to get to the sub menu.
int main()
{
sqlite3 *db;
int rc;
rc = sqlite3_open_v2("test.db", &db, SQLITE_OPEN_READWRITE, NULL);
if (rc != SQLITE_OK)
{
cout << "Error opening database: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
return 0;
}
else
{
cout << "Database opened successfully." << endl;
}
cout << "Welcome to Database" << endl;
int choice = mainMenu();
while (true)
{
switch (choice){
case 1:
addMenu();
break;
case 2:
updateMenu();
break;
case 3:
deleteCustomer(db);
break;
case -1:
return 0;
default:
cout << "That is not a valid choice." << endl;
cout << "\n\n";
choice = mainMenu();
}
}
sqlite3_close(db);//closes the database
return 0;
}
void printMainMenu()
{
cout << "Please choose an option (enter -1 to quit): " << endl;
cout << "1. Add" << endl;
cout << "2. Update" << endl;
cout << "3. Delete" << endl;
cout << "4. Make a transaction" << endl;
cout << "Enter choice: ";
}
int mainMenu()
{
int choice = 0;
printMainMenu();
cin >> choice;
while ((!cin || choice < 1 || choice > 4) && choice != -1)
{
if (!cin)
{
resetStream();
}
cout << "That is not a valid choice." << endl
endl;
printMainMenu();
cin >> choice;
}
return choice;
}
void addMenu()
{
cout << "Please choose an option (enter -1 to quit): " << endl;
cout << "1. Add customer" << endl;
cout << "2. Add product" << endl;
cout << "Enter choice: ";
}
The Add Menu is typical
You are on the right track. Each menu runs a loop, and each menu item corresponds to a function that carries out its actions. Sometimes that means calling a function that is a "sub-menu"; other times that means calling a function that does more than that.
Inside the loop, you display the menu, and input the user's choice. A switch statement, based on the user's choice, selects which function to call.
The Add Menu from the OP is a typical example.
Function
add_menuuses anenumto dress-up the switch statement. It also usesstd::unreachable, a C++23 feature that is typically optimized away in release buids, but which translates into something likeassert(false)in debug builds.The only tricky part is the return value. The return value from one menu function becomes the
doneflag in the caller. When you returntrue, that sets thedoneflag in the caller.Each of the menus in the program below returns
false. That causes the corresponding parent menu to be redisplayed. Were a menu function to returntrue, that would cause the parent menu to be exited, without being redisplayed.The other thing that streamlines the menu functions is function
get_int.Function
get_inthandles keyboard inputFunction
get_intis a robust routine that handles input fromstd::cin. It protects against all the usual errors that happen withstd::cin. Because it usesstd::getlinefor all keyboard input, it won't causecinto fail when the user accidentally enters non-numeric data. It also performs range checks on the numbers that are entered, rejecting any that are out of range. It even has a cancel feature that allows the user to abort an input operation by pressing Enter on a blank line.Note, however, that the cancel option can be disabled, which was done in all of the menus used here.
A call to
get_intcan have only two outcomes: 1. A valid, in-range integer is input, or 2. the user cancels.get_intreturnstruewhen a number is successfully entered, andfalsewhen the user cancels. The entered number is returned via a reference parameter (variablechoicein the example below).Here is the declaration for function
get_int. Complete source code, along with a detailed explanation of how it works, can be found in this StackOverflow answer.A complete program
The following program demonstrates the menu functions in action.
Here is the output from a sample run: