You have at least these two options:
You could put the "user menu" into its own function and make this function only return once the user has left this menu and of all its sub-menus.
You could introduce an additional variable into the program which specifies in which menu the user currently is, and modify this variable as appropriate.
Option #1 is easier to implement if there is a strict menu hierarchy (i.e. if you go down the menu hierarchy through a certain menu, then you will always go through the same menu again when going back up the hierarchy). However, if you need to be able to jump freely between all menus (i.e. there is no strict menu hierarchy), then option #2 is better.
In your case, you seem to have a strict menu hierarchy, so option #1 will probably be better:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//forward declarations
void home_menu( void );
void user_menu( void );
int main( void )
{
home_menu();
}
void home_menu( void )
{
char answer[6];
//stay in home menu forever, until user explicitly quits
for (;;) //infinite loop, equivalent to "while(1)"
{
printf("*****************************************************************\n");
printf("*\t\t\t HOME SCREEN \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*\t Do you wish to continue as a user or as an admin ? \t*\n");
printf("*\t (type your answer) \t\t\t\t\t*\n");
printf("*\t Press 0 to exit the program \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*****************************************************************\n");
//repeat until user input is valid
for (;;)
{
//attempt to read one word from user
//Note that the program will misbehave if user enters more than
//one word, so it may be better to use the function "fgets"
//instead, which will read an entire line instead of a
//single word.
if ( scanf( "%5s", answer) != 1 )
{
fprintf( stderr, "input failure!\n" );
exit( EXIT_FAILURE );
}
//handle user input
if ( strcmp( answer, "0" ) == 0 )
{
printf( "Exiting program...\n" );
return;
}
else if ( strcmp( answer, "user" ) == 0 )
{
user_menu();
}
else if ( strcmp( answer, "admin") == 0 )
{
printf( "NOT YET IMPLEMENTED\n" );
continue;
}
else
{
//user input was not ok, so reprompt user for input and
//restart the loop iteration
printf("Wrong answer. Please type in one of the available options.\n");
continue;
}
//user input was ok, so we can break out of the
//inner infinite loop
break;
}
}
}
void user_menu( void )
{
int answer;
//stay in user menu forever, until user explicitly logs out
for (;;)
{
printf("*****************************************************************\n");
printf("*\t\t\t USER SCREEN \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*\t1) SIGNUP \t\t\t\t\t\t*\n");
printf("*\t2) LOGIN \t\t\t\t\t\t*\n");
printf("*\t3) LOGOUT \t\t\t\t\t\t*\n");
printf("*\t(type in the desired number) \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*****************************************************************\n");
for (;;)
{
if ( scanf( "%d", &answer ) != 1 )
{
fprintf( stderr, "input failure!\n" );
exit( EXIT_FAILURE );
}
switch ( answer )
{
case 1:
printf( "NOT YET IMPLEMENTED\n" );
continue;
case 2:
printf( "NOT YET IMPLEMENTED\n" );
continue;
case 3:
printf( "Logging out, returning to home menu.\n" );
return;
default:
printf( "Wrong answer. Please type in one of the available options.\n" );
continue;
}
//this line is currently unreachable, but this may
//change as more options are implemented
//input was ok, so we can break out of the inner infinite loop
break;
}
}
}
If you don't want to have the restrictions of a strict menu hierarchy, then, as already mentioned, you will have to store the menu state (i.e. which represents the menu in which the user currently is) in an additional variable. It would still appropriate to store every menu in its own function. However, since the menu system is no longer hierarchical, when a sub-menu is finished, it should no longer return to the parent menu. This means that a menu-handling function should return immediately, instead of continuing to run while sub-menus are being processed. The return value of these functions should always be the new menu state:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum menu_state
{
MENUSTATE_QUITPROGRAM,
MENUSTATE_HOME,
MENUSTATE_USER,
MENUSTATE_USER_SIGNUP,
MENUSTATE_USER_LOGIN,
MENUSTATE_USER_LOGOUT,
MENUSTATE_ADMIN
//add one additional state for every new menu
};
//forward declarations
enum menu_state home_menu ( void );
enum menu_state user_menu ( void );
enum menu_state user_signup_menu ( void );
enum menu_state user_login_menu ( void );
enum menu_state user_logout_menu ( void );
enum menu_state admin_menu ( void );
int main( void )
{
enum menu_state ms = MENUSTATE_HOME;
while ( ms != MENUSTATE_QUITPROGRAM )
{
switch ( ms )
{
case MENUSTATE_HOME:
{
ms = home_menu();
break;
}
case MENUSTATE_USER:
{
ms = user_menu();
break;
}
case MENUSTATE_USER_SIGNUP:
{
ms = user_signup_menu();
break;
}
case MENUSTATE_USER_LOGIN:
{
ms = user_login_menu();
break;
}
case MENUSTATE_USER_LOGOUT:
{
ms = user_logout_menu();
break;
}
case MENUSTATE_ADMIN:
{
ms = admin_menu();
break;
}
default:
{
//this label only exists to suppress a warning message
//from the compiler
}
}
}
}
enum menu_state home_menu( void )
{
char answer[6];
printf("*****************************************************************\n");
printf("*\t\t\t HOME SCREEN \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*\t Do you wish to continue as a user or as an admin ? \t*\n");
printf("*\t (type your answer) \t\t\t\t\t*\n");
printf("*\t Press 0 to exit the program \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*****************************************************************\n");
//repeat until user input is valid
for (;;)
{
//attempt to read one word from user
//Note that the program will misbehave if user enters more than
//one word, so it may be better to use the function "fgets"
//instead, which will read an entire line instead of a
//single word.
if ( scanf( "%5s", answer) != 1 )
{
fprintf( stderr, "input failure!\n" );
exit( EXIT_FAILURE );
}
//handle user input
if ( strcmp( answer, "0" ) == 0 )
{
printf( "Exiting program...\n" );
return MENUSTATE_QUITPROGRAM;
}
if ( strcmp( answer, "user" ) == 0 )
{
return MENUSTATE_USER;
}
if ( strcmp( answer, "admin") == 0 )
{
return MENUSTATE_ADMIN;
}
//user input was not ok, so reprompt user for input
//the (infinite) loop will automatically repeat
printf("Wrong answer. Please type in one of the available options.\n");
}
}
enum menu_state user_menu( void )
{
int answer;
printf("*****************************************************************\n");
printf("*\t\t\t USER SCREEN \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*\t1) SIGNUP \t\t\t\t\t\t*\n");
printf("*\t2) LOGIN \t\t\t\t\t\t*\n");
printf("*\t3) LOGOUT \t\t\t\t\t\t*\n");
printf("*\t(type in the desired number) \t\t\t\t*\n");
printf("*\t\t\t \t\t\t\t\t*\n");
printf("*****************************************************************\n");
for (;;)
{
if ( scanf( "%d", &answer ) != 1 )
{
fprintf( stderr, "input failure!\n" );
exit( EXIT_FAILURE );
}
switch ( answer )
{
case 1:
return MENUSTATE_USER_SIGNUP;
case 2:
return MENUSTATE_USER_LOGIN;
case 3:
return MENUSTATE_USER_LOGOUT;
}
printf( "Wrong answer. Please type in one of the available options.\n" );
}
}
enum menu_state user_signup_menu( void )
{
printf( "NOT YET IMPLEMENTED\n" );
printf( "Returning to user menu.\n" );
return MENUSTATE_USER;
}
enum menu_state user_login_menu( void )
{
printf( "NOT YET IMPLEMENTED\n" );
printf( "Returning to user menu.\n" );
return MENUSTATE_USER;
}
enum menu_state user_logout_menu( void )
{
printf( "Logging out.\n" );
printf( "Returning to home menu.\n" );
return MENUSTATE_HOME;
}
enum menu_state admin_menu( void )
{
printf( "NOT YET IMPLEMENTED\n" );
printf( "Returning to home menu.\n" );
return MENUSTATE_HOME;
}