0

I am trying to write a calculator program in C which only allows digits. If a calculation is finished, the program should ask if you want to calculate again.

If you type a character for an operand the calculator should print that the operand is not valid.

That works so far, but if I type a character after the first calculation my if-statement (to print that the operand is not valid) is not working anymore.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main() {
    float operand1, operand2, result;
    char operator;
    char YN; // yes/no

    do {
      printf("Enter a formula (+, -, *, / are possible):\n");
      scanf("%f %c %f",&operand1, &operator, &operand2);
      if (operand1!=(int)operand1 || operand2!=(int)operand2) {
        printf("operand not valid!\n");
        return 0;
      }
      scanf("%c", &YN);
        
      switch (operator) { 
        case '+':
          result = operand1 + operand2;
          printf("The sum of %.0f and %.0f is %f\n", operand1, operand2, result);
          break;
        case '-':
          result = operand1 - operand2;
          printf("The difference of %.0f and %.0f is %f\n", operand1, operand2, result);
          break;
        case '*':
          result = operand1 * operand2;
          printf("The product of %.0f and %.0f is %f\n", operand1, operand2, result);
          break;
        case '/':
          if (operand2 != 0) {
            result = operand1 / operand2;
            printf("The quotient of %.0f and %.0f is %f\n", operand1, operand2, result);
          } else {
            printf("operand2 cant be 0.\n");
          }
          break;
        case '%':
          printf("The remainder of .0%d and %.0d is %d\n", (int)operand1, (int)operand2, (int)result);
          break;
        case 'M':
          if (operand1 > operand2) {
            result = operand1;
            printf("The maximum of %.0f and %.0f is %f\n", operand1, operand2, result);
          } else if (operand1 < operand2) {
            result = operand2;
            printf("The maximum of %.0f and %.0f is %f\n", operand1, operand2, result);
          } else {
            printf("The values are the same.\n");
          }
          break;
        case 'm':
          if (operand1 < operand2) {
            result = operand1;
            printf("The minimum of %.0f and %.0f is %f\n", operand1, operand2, result);
          } else if (operand1 > operand2) {
            result = operand2;
            printf("The minimum of %.0f and %.0f is %f\n", operand1, operand2, result);
          } else {
            printf("The values are the same.\n");
          }
          break;
        default:
          printf("Operator '%c' not valid!\n", operator);
          return 0;
      }

    printf("Do you want to calculate something else? Y/N):\n");
    scanf("%c", &YN);
    fflush(stdin);
    } while (YN == 'y' || YN == 'Y');
    
    return 0;
}

Problem:

The if-statment to check if the operands are integers is not working anymore after the first calculation.

        if (operand1!=(int)operand1 || operand2!=(int)operand2) {
            printf("operand not valid!\n");
            return 0;
        }

e.g. Input:

2+3

it prints - The sum of 2 and 3 is 5

Do you want to calculate something else?

y

b+1

prints - The sum of 1 and 3 is 4

But it should print - operand not valid!

It works if you type a character in the first calculation.

I really need your help. Could you please fix my code so that the if-statement is also working for multiple calculations. Your help is very much appreciated.

joojey
  • 3
  • 3
  • Relying on (indeterminate) values of uninitialized variable is bad and invokes *undefined behavior*. Instead of that, you should check the return values of `scanf()` to see if if succesfully read required things. – MikeCAT Oct 17 '20 at 01:07
  • Also note that [`fflush(stdin);` invokes *undefined behavior*](https://stackoverflow.com/questions/2979209/using-fflushstdin). – MikeCAT Oct 17 '20 at 01:08

1 Answers1

0

Values of uninitialized non-static local variables are indeterminate and you mustn't rely on their values because using the values invokes undefined behavior.

Instead of that, you should check return values of scanf() to check if it successfully read required things.

This means that instead of this

        scanf("%f %c %f",&operand1, &operator, &operand2);
        if (operand1!=(int)operand1 || operand2!=(int)operand2) {
            printf("operand not valid!\n");
            return 0;
        }

You should do

        if (scanf("%f %c %f",&operand1, &operator, &operand2)!=3 || operand1!=(int)operand1 || operand2!=(int)operand2) {
            printf("operand not valid!\n");
            return 0;
        }
MikeCAT
  • 73,922
  • 11
  • 45
  • 70