# Thread: Infinte loop with switch, Why??

1. ## Infinte loop with switch, Why??

Hi,
I have made a simple menu program and use switch to handle the choices. The problem is, if i enter a number, it sends it into an infinite loop instead of the default command to say invalid input.
Does anyone know why this is?
Thanks

Code:
```#include <stdio.h>

{
float a, b, ans;
a = 0;
b = 0;
ans = 0;

printf("********************************\n");
scanf("%f", &a);
scanf("%f", &b);

ans = a+b;

printf("\n %f plus %f equals %f \n", a, b, ans);

}

void subtract()
{
float a, b, ans;
a = 0;
b = 0;
ans = 0;

printf("********************************\n");
printf("          SUBTRACTION\n\n");
printf("Enter Minuend: ");
scanf("%f", &a);
printf("Enter Subtrahend: ");
scanf("%f", &b);

ans = a-b;

printf("\n %f minus %f equals %f \n", a, b, ans);

}

void multiply()
{
float a, b, ans;
a = 0;
b = 0;
ans = 0;

printf("********************************\n");
printf("        MULTIPLICATION\n\n");
printf("Enter Multiplicand: ");
scanf("%f", &a);
printf("Enter Multiplier: ");
scanf("%f", &b);

ans = a*b;

printf("\n %f plus %f times %f \n", a, b, ans);

}

void divide()
{
float a, b, ans;
a = 0;
b = 0;
ans = 0;

printf("********************************\n");
printf("          DIVISION\n\n");
printf("Enter Dividend: ");
scanf("%f", &a);
printf("Enter Divisor: ");
scanf("%f", &b);

ans = a/b;

printf("\n %f divided by %f equals %f \n", a, b, ans);

}

void retry()
{
}

{
int ans = 0;

printf("\n\nWhat would you like to do?\n");
printf("2. Subtract: \n");
printf("3. Multiply: \n");
printf("4. Divide: \n");
scanf("%d", &ans);

switch(ans)
{
case 1:
break;
case 2:
subtract();
break;
case 3:
multiply();
break;
case 4:
divide();
break;
default:
printf("Invalid input!!\n");
retry();
break;
}
}

int main()
{
return 0;
}```

2. Well for starters you're recursively calling menu. (The entire "retry" function is pointless, since you can just call menu directly anyway.) A loop would work better. Next, how about actually checking the return value of scanf to make sure they entered a number instead of something else?

Quzah.

3. > printf("Invalid input!!\n");

> scanf("%d", &ans);
scanf() stops processing at the first character which does NOT match the conversion.
The bad news for you is that input is NOT processed either, so unless you actually do something with the input, then scanf() gets stuck.

This is what not to do
http://faq.cprogramming.com/cgi-bin/...&id=1043284351

http://faq.cprogramming.com/cgi-bin/...&id=1043284385

Also, you should have a while loop around your menu(). Calling functions recursively like you do is not good.

4. Another quick and dirty solution (above the one suggested by quzah: check scanf() return code) could be to flush standard input before scanf(): fflush(stdin) before scanf() could do the trick.

But even in this case, if you put a breakpoint at start of menu(), you will see that your stack is growing and growing... This is due to the fact that menu() is called recursively and the stack never unwinds.

So, instead of calling retry() at end of menu(), a goto to start of menu() or a big while (1) wrapping the whole menu() function (for purists ) is mandatory.

Best regards, bilbo

5. fflush(stdin) before scanf() could do the trick.
That's not a solution. That's a problem. fflush is NOT for input streams! Ever. Any attempt to do so is undefined which means anything or nothing can happen. It was never ever intended for input streams. Then you go on to suggest goto? Why not tell them to use gets while you're at it?

Quzah.

6. Originally Posted by quzah
That's not a solution. That's a problem. fflush is NOT for input streams! Ever. Any attempt to do so is undefined which means anything or nothing can happen. It was never ever intended for input streams.
Sorry, quzah, I am new to this board (I have just subscribed today) and in a rush of giving my contribute I have not yet read the fuc*ed FAQ.
I just thought that Kate was using Microsoft Visual C, where fflush(stdin) is perfectly legal (it is effectively seen as an extension to the C standard). Look at http://msdn.microsoft.com/library/en...crt_fflush.asp for a sample code.
In fact, before answering, I tried my suggestion (with MSVC compiler) and it worked...

Originally Posted by quzah
Then you go on to suggest goto? Why not tell them to use gets while you're at it?
I based my suggestion on the result. The result is the way a program will work; the result is the compiled machine code which will allow the program to run.
Now, please, look at the machine code that the compiler (alas... again the Microsoft one...) will generate for a goto and for a while...

Code:
```           while (1) a = 3;
mov eax,1
test eax,eax
je ...  // OUT OF LOOP
mov dword ptr [a],3
jmp ...  // START OF LOOP```
and this is for the goto...
Code:
```           retry: a = 3; goto retry;
mov dword ptr [a],3
jmp retry```
The second one seems even more compact than the first one, isn't it?

Best regards, bilbo

P.S. Ah, fortunately "goto" is not in the FAQ! Anyway you must give me credit that I did not discredit the purists!

P.P.S Well, I hope we will become friends, if you leave me the time to make some other contribution, instead of flaming as fast as you can!

7. The reason we usually steer people away from goto is that it makes for horrible debugging and readability. It's also one of the reasons I don't like globals in general. It's too annoying to try and figure out where they're at, rather than just looking for defined variables at the top of the function / code block.

Goto has its uses, and I wasn't debating speed. It's just not the best way to teach people how to control the flow of their application.

As for fflush, I, as well as many others here, feel it's best to only present people with standard methods for handling problems. Especially considering there is a standard way to handle the flushing of the input stream. (It's quite a common topic, the board search and/or FAQ will cover it if you're curious.)
I just thought that Kate was using Microsoft Visual C,
That's the problem with non standard methods. We have no idea what compiler they're using, so why limit them to a "solution" that may or may not work for them, when we can provide on that will guarinteed fix the issue?

Quzah.

8. Thanks guys,

Great help

9. Originally Posted by quzah
As for fflush, I, as well as many others here, feel it's best to only present people with standard methods for handling problems.
Ok, quzah, got it! Next time I'll specify "this is valid only for MSVC, or GCC, or something else", or - better - I'll avoid to suggest non-standard solutions, as you pointed out.

Originally Posted by quzah
The reason we usually steer people away from goto is that it makes for horrible debugging and readability. It's also one of the reasons I don't like globals in general.
Sorry, quzah, I - not always but sometimes - think goto is more readable because it avoids a lot of indenting in the code lines; or, using it, the creation of helper variables to go out of nidified loops can be avoided.
And I - not always but sometimes - like globals because they do not need to be passed on the stack when calling some related function. I know, it is harmful, collateral effects may arise, etc etc, but I think the skill of the people, among many other things, can be evaluated by the way they are able of playing with fire... Anyway, I respect your point of view.

Best regards, bilbo