Why is the following program stuck in a loop?

旧时模样 提交于 2019-12-02 11:06:12

The result of scanf is the number of fields assigned. If scanf returns 0, it will return 0 for the same format string every time you call it. Because scanf pushes back the last character it read that does not match the input sequence (%f), it will repeatedly try to convert the same string over and over.

That's why you loop infinitely. You might want to check the result of scanf. If it's less than 2, error out.

I think you would need to make your input routine more robust than scanf (apparently) is. For example, if you read your input in whole lines, you can parse them (say, using sscanf) to get the components w/o mucking up the input stream.

scanf is reading until it can parse a floating point number. Try using gets to read in a string and then parse that string from there.

http://www.cplusplus.com/reference/clibrary/cstdio/gets/

I guess that to exit you need to enter a float + 'E' (0.0 E) and not just 'E'. Would that be what you're asking about?

Ah! I see you mentioned placing things backward. Yes. scanf() is never going to detect that.

If you're under Linux, check out lex and yacc (or flex and bison to be precise.) To do things like these, it's a lot better and you can make things a lot better (support parenthesis, minus and plus operator, instead of just add and subtract, etc.)

It's not "stuck in a loop", it's waiting for the operator that this line:

        scanf ("%f %c", &b, &operator);

promises. That line reads until it receives a floating-point number, and then it reads an operator. If you give it an operator first, it will simply ignore it.

(By the way, you should initialize operator to something specific before getting to the line while ( operator != 'E') {, because for all you know, operator might happen to start out as 'E'. Also, as Mysticial says, operator isn't a great name for a C identifier, because of its uses in C++.)

The problem is that scanf() is trying to read what you told it to, that is, a floating point number and a character. When you type the other way around scanf returns because its not the format you told it too, but unfortunately it WONT flush the buffer, so the while would go again and scanf tries to read again, and so on.

Drop scanf, although if this is only for a homework you may try doing:

 if (!scanf ("%f %c", &b, &operator)) {
    scanf ("%*[^\n]"); /* TRY to flush stdin */
    printf("Incorrect input!");
    incorrect_input++;
    continue;
  } else {
    incorrect_input = 0;
  }

  if (incorrect_input > 5) {
      break; /* Very simple measure to avoid getting stuck in the loop */
  }

However, when I enter operators in wrong order, like this: "/ 2" or "* 10", the program is stuck in a loop.

How do I fix this bug so that when the operators are entered in wrong order, it just prints "Unknown operator"?

You might want to read the entire expression and then parse it for correctness. There are various expression notation methods (infix, postfix (also known as reverse polish notation) and prefix (otherwise known as polish notation)) which makes the task of validating and evaluating them easier.

Also if you have or can get hold of the "The C Programming Language" book written by Dennis Ritchie and Brian Kernighan, turn to chapter 4 and read the section that walks you through the design and implementation of a calculator program.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!