views:

136

answers:

1

Hi,

This must be very simple but since coming from Java world I feel a bit in the woods in this case.

while (operator != 'E') {
  NSLog(@"Enter:");
  scanf("%lf %c", &value2, &operator);

  switch (operator) {
   case 'S':
    [deskCalc setAccumulator:value2];
    break;
   case 'E':
    break;
   case '+':
    [deskCalc add:value2];
    break;
   case '-':
    [deskCalc subtract:value2];
    break;
   case '/':
    [deskCalc divide:value2];
    break;
   case '*':
    [deskCalc multiply:value2];
    break;
   default:
    NSLog(@"Unknown command");
    break;
  }

  NSLog(@"=%g", [deskCalc accumulator]);

 }

Now if I enter just 'e' or some other characters without entering the number first the program goes into loop like this:

2010-02-08 13:44:38.690 Calculator[89939:a0f] Enter:
2010-02-08 13:44:38.691 Calculator[89939:a0f] Unknown command
2010-02-08 13:44:38.691 Calculator[89939:a0f] =10
2010-02-08 13:44:38.692 Calculator[89939:a0f] Enter:
2010-02-08 13:44:38.692 Calculator[89939:a0f] Unknown command
2010-02-08 13:44:38.693 Calculator[89939:a0f] =10

Why scanf doesn't block the thread and ask for correct input again?

Thanks Noi

+3  A: 

This is not an ObjC problem but a C problem.

The problem is not blocking the thread. In your scanf, you demand a floating point number (%lf) followed by some whitespaces (), and then a character (%c). But when you enter e, it is not a valid floating point number, so scanf fails immediately.

But the invalid character e is still left in the buffer. So, in the next operation with stdin, you ask for a floating point number again, and it fails and immediately return again because e is still not valid, and then the next scanf asks for a floating pointer number again, ad infinitum.

See http://stackoverflow.com/questions/1716013/scanf-causing-infinite-loop for detail.

The safer alternative is to use fgets to read the raw input, then parse the received string to get value2 and operator.

KennyTM
So if scanf fails once, it cannot work with the same variables again? If matching fails the while loop becomes infinite since scanf doesn't block for user's input. It messes up something under the hood, I guess. And I want to understand what exactly.
noi
@noi: See update.
KennyTM
Thank you, KennyTM, it's all clear now.
noi