I am implementing a Stack data structure using an array. To perform an operation on a stack like Push or Pop or Exit from Program, I am taking an input from a user in the form of an integer(Say 1 for Push).
For taking an input from a user continuously, I am running a while(1) loop and inside a loop asking a user to give an integer as an input for required operation.
Problem: during the execution, the program is not waiting for a user to give input and goes into infinite loop. I have tried to clear stdin using fflush but still not working.
Please look at the code below with given comments and help.
Thanks.
//Main function
int main(){
STACK marks, roll_number; //marks and roll_number are two stacks of type STACK
//Initialize both Stacks with required size
initStack(&marks, 10);
initStack(&roll_number, 10);
int choice, marks_data;
//Menu for user to choose from available operations
printf("1. Push\n");
printf("2. Pop\n");
printf("3. Exit\n");
//Taking user input for operations
while(1){
printf("Enter choice of Operation:\n");
//Clearing standard input. Although not a best practice but implementing to
//take user input
fflush(stdin);
// program is not stopping here and taking invalid choice
//hence executing 'default statement' of switch case
scanf("%d", &choice);
switch(choice){
case 1: printf("Enter Marks");
scanf(" %d", &marks_data);
push(&marks, marks_data);
break;
case 2: marks_data = pop(&marks);
printf("Deleted Data : %d\n", marks_data);
break;
case 3: exit(0);
default: printf("Invalid Choice of Operation !!\n");
}
//using to clear \n character from user and taking valid input
printf("Press Enter Key to continue...");
while(getchar() != '\n')
getchar();
}
return 0;
}
When you use scanf
, you have to put your "account's hat" on and account for all characters either read from the input buffer, or left unread in the input buffer. This is especially true when mixing input between numeric and character input or when mixing input functions in your code.
In your case, you call scanf ("%d", ...)
for choice
and marks
, but then attempt to control your loop execution with:
printf("Press Enter Key to continue...");
while(getchar() != '\n')
getchar();
As a good scanf
accountant, you know reading using the '%d'
format specifier will read digits from stdin
up to the first non-digit character and terminate the read, leaving the non-digit character in stdin
unread. (presuming no stray characters were entered following choice
or mark
), that will be the '\n'
character generated by pressing Enter following your previous input.
When you test while(getchar() != '\n')
, the first character read is likely the '\n'
character, causing your loop to test TRUE and skip the getchar()
call within the loop.
The easiest solution is just to add an additional getchar()
below your current one.
Next fflush(stdin)
is Undefined Behavior on just about all systems except windows. On Linux, fflush(stdin)
is defined, but only for seekable streams -- which only applies to stdin
if a file has been redirected to your program on stdin
, e.g.
./yourexe < somefile.txt
Otherwise fflush(stdin)
is not defined. So you have to ask yourself -- being non-portable on everything but windows unless stdin
is seekable as the result of redirection -- "Is is really good practice to use anywhere?" and "How do I force the user to redirect a file to stdin
?" (you can't). So best to avoid all the way around.
Look things over and let me know if you have further questions.