Home > Blockchain >  С - Why scanf() in if() statement works incorrect?
С - Why scanf() in if() statement works incorrect?

Time:09-27

I am trying to make calculator in command line application, but when I use `

int a, b, result;
printf("Enter problem:\n");

if(scanf("%i %i", &a, &b))
{
    result = a   b;
    printf("%i\n", result);
}
else if(scanf("%i*%i", &a, &b))
{
    result = a * b;
    printf("%i\n", result);
}

If I write 5 5 , I have 10, but when I 5*5 it shows 32771. If I swap those statements, when I write 5*5 , I have 25, but when I write 5 5, I have 32771 too. Thanks in advance for answer!

CodePudding user response:

if(scanf("%i %i", &a, &b))  

that line makes no sense as scanf returns the number of successfully scanned items.

If you want to check if scanf succeeded

if(scanf("%i %i", &a, &b) == 2) 

The rest is invalid as scanf reads the data from the input stream and the second scanf will not have the full line to scan.

char line[100];
fgets(line, 100, stdin);  // check for errors
if(sscanf(line, "%i %i", &a, &b) == 2)
{
    result = a   b;
    printf("%i\n", result);
}
else if(sscanf(line, "%i*%i", &a, &b) == 2)
{
    result = a * b;
    printf("%i\n", result);
}
else
{
    printf("Invalid Input\n");
}

CodePudding user response:

That's because scanf works differently to what you think it does.

If you write "5*5" and use the above code, the first if statement is executed. scanf scans string, parses the first number and then it hits '*' which DOES NOT match the format string. scanf exits and returns 1 as this is the number of matched strings. The first branch is executed and you are using uninitialized variable b in the addition hence the nonsense result.

If you want to parse arithmetic operations you have to write the logic yourself.

CodePudding user response:

As the other answers have pointed out, you're not using scanf correctly - if you type 5 * 5, the first scanf successfully reads 5 into a, then bails because * isn't the expected and b isn't updated. However, because you had one successful conversion and assignment, scanf returns 1 so the first branch is taken.

While this is Not The Way To Do It™, a quick-and-dirty solution would be to scan for three inputs - the two operands and the operator, then branch based on the value of the operator:

int a, b, result;
char op;

if ( scanf( "%d %c %d", &a, &op, &b ) == 3 )
{
  switch( op )
  {
    case ' ' : result = a   b; break;
    case '-' : result = a - b; break;
    case '*' : result = a * b; break;
    case '/' : result = a / b; break;
    default: fprintf( stderr, "Unrecognized operator %c - exiting\n", op ); return -1;
  }
}
else
{
  fprintf( "Badly formatted input...exiting\n" );
  return -1;
}
printf( "%d %c %d = %d", a, op, b, result );

Usually, though, parsing arithmetic expressions is a little more involved than that.

  •  Tags:  
  • c
  • Related