while (option){
printf("\nPress 0 : Exit\nPress 1 : Enqueue\nPress 2 : Dequeue\nPress 3 : Peek\nPress 4 : Isempty\nPress 5 : Isfull\nPress 6 : Size\nPress 7 : Display\n");
scanf("%d", &option);
if(option == 1){
Enqueue();
}else if(option == 2){
Dequeue();
}else if(option == 3){
Peek();
}else if (option == 4){
Isempty();
}else if(option == 5){
Isfull();
}else if(option == 6){
Size();
}else if(option == 7){
Display();
}else if(option == 0){
printf("\nBYE\nBYE\nBYE");
}else{
printf("\nWRONG INPUT!!");
}
}
Why is that every time I enter anything except 0 to 7, this while loop starts running infinitely ?
Using the man page for scanf, which redirects to the man page for sscanf, I can find the following about input and formats:
A sequence of characters from the input is converted according to this specification, and the result is placed in the corresponding pointer argument. If the next item of input does not match the conversion specification, the conversion fails—this is a matching failure.
Reading a charactger like g
is a matching failure (here, it is both the first and the next item of input). The character, g
, however, is not read (you’ll find that the return value of scanf
is 0: zero characters were read), and it is still in the standard input(!) (stdin). Thus, the if-else chain runs through with the default for option
(1), then returns to printing the choices, and then reads the same character again. Ad infinitum.
Testing for the number of characters successfully read with scanf
will not help, since you want the prompt to reappear, not exit the while loop, on bad input, and the character is still on stdin.
What you probably should do, is use a function that can read any input, and try to convert that input to an integer. That way, you will always cleanly read stdin, while also (manually) handle any errors.
Functions to use would be fgets
to read a line into a string, and then strtol
to safely convert that string to an integer.
The answer by gulpr does this, albeit it slightly differently; my explanation above is an attempt at explaining why you get the results you’re seeing with your own code.
- I suggest to read the input as a string and handle incorrect input yourself.
switch case
is more suitable.- change the loop
int option;
char str[32];
do{
option = 0;
printf("\nPress 0 : Exit\nPress 1 : Enqueue\nPress 2 : Dequeue\nPress 3 : Peek\nPress 4 : Isempty\nPress 5 : Isfull\nPress 6 : Size\nPress 7 : Display\n");
if(fgets(str, sizeof(str), stdin))
{
if(sscanf(str, "%d", &option) != 1) option = 100;
}
switch(option)
{
case 1:
//Enqueue();
break;
case 2:
//Dequeue();
break;
case 3:
//Peek();
break;
/* more options */
case 0:
printf("\nBYE\nBYE\nBYE");
break;
default:
printf("\nWRONG INPUT!!");
break;
}
}while (option);
}
Scanf tries to read the type of data you want. If scanf can’t complete the line or the data is not compatible, it passes the remaining values as input to next scanf function. So if there is a next scanf function in the code, that function not waits for the input.
Actually when you pass a number to the console it is not only number:
char alpha;
char beta;
int main(void){
scanf("%c",&alpha);
scanf("%c",&beta);
printf("alpha as decimal : %d\n",alpha);
printf("beta as decimal : %d\n",beta);
}
When you run this code, you can put one input instead of two. There is a two scanf function but when you pass a value to the console and press enter, it becomes char and a linefeed (example : “W\n”). First scanf function reads the “W” value and passes the remaining value(“\n”) to the next scanf function. Linefeed value is 10 by decimal ascii.
In your example, scanf continuously can’t read the data, so passes as input to next scanf function.
NO, the thing is the loop starts running infinitely when I enter a character(a-z). It doesn’t take any input further.
I think while(option) should just be while(true). option is not a boolean expression/conditional.
How is
option
declared and initialized?Which one ? please be precise in your answers, and give the program output, or relevant part of it. I see nothing wrong in the code you posted for now.
Conclusion:
scanf
is not the right function to be used for interactive input, because handling of input thatscanf
cannot handle (such as entering foo whenscanf
expects an integer because of the%d
specifier) is close to impossible. See answers belowShow 23 more comments