Search code examples
cscanfcalculatorcomplex-numbers

Scanning operator before scanning the numbers for a complex number calculator gives an error but it doesn't when operator is scanned after numbers


Here are the issues (mostly fixed now):

  1. Position of scanf for operator shouldn't matter in this particular code but apparently it does when it is written after prompts to scan the numbers.
  2. Case '/' gives 0.00 as an output every time even though the logic seems correct to me.
  3. The purpose of scanning operator before numbers was that if the user chooses a different operator than the ones hardwired in the program, the program would simply return an error message instead of making the user type in values of the numbers and then get the error message through switch case. But I can't figure out how to do that.

Here's the fixed code:

#include <stdio.h>

int main(){
typedef struct complex_numbers
{
    float real;
    float imag;
}complex;
complex c1, c2, sum_c, sub_c, pro_c, div_c;
printf("Enter the real part of the first complex number : ");
scanf("%f", &c1.real);
printf("Enter the imaginary part of the first complex number : i*");
scanf("%f", &c1.imag);
printf("Enter the real part of the second complex number : ");
scanf("%f", &c2.real);
printf("Enter the imaginary part of the second complex number : i*");
scanf("%f", &c2.imag);
printf("Numbers entered are: %.2f + i*%.2f & %.2f + i*%.2f\n", c1.real, c1.imag, c2.real, c2.imag);
char operator;
printf("Enter operator '+'||'-'||'*'||'/': ");
scanf(" %c", &operator);
switch (operator)
{
case '+':
sum_c.real= c1.real+ c2.real;
sum_c.imag= c1.imag+ c2.imag;
printf("Sum of the numbers is: %.2f + i*%.2f", sum_c.real, sum_c.imag);
break;
case '-':
sub_c.real= c1.real- c2.real;
sub_c.imag= c1.imag+ c2.imag;
printf("Difference of the numbers is: %.2f + i*%.2f", sub_c.real, sub_c.imag);
break;
case '*': 
pro_c.real= c1.real* c2.real+ (c1.imag* c2.imag)*(-1);
pro_c.imag= c1.real* c2.imag+ c1.imag* c2.real;
printf("Product of the numbers is: %.2f + i*%.2f", pro_c.real, pro_c.imag);
break;
case '/':
if((c2.real&& c2.imag)==0){
    printf("Error: Invalid denominator!");
    return 1;
}
div_c.real= (float)(c1.real* c2.real+ (-1)*(c1.imag* (-c2.imag)))/(c2.real* c2.real+ c2.imag* c2.imag);
div_c.imag= (float)(c1.real* (-c2.imag)+ c1.imag* c2.real)/(c2.real* c2.real+ c2.imag* c2.imag); 
printf("Division of the numbers is: %.3f + i*%.3f", div_c.real, div_c.imag);
break;
default:
printf("Error: Invalid operator!");
break;
}
return 0;
}

Solution

  • This is because scanf("%c", &operator); will read the newline character (\n) that is still in the input after reading the previous digit. The %c conversion specifier is one of the exceptions in that it does not skip leading whitespace. This is why reading the operator first works (there's no newline in the input), but reading it after reading the digits does not.

    One way to resolve this, is to add a space character before the %c in the format string:

    scanf(" %c", &operator);
    

    See here for the exact specifications of scanf and the format string.

    To catch these types of errors, you may want to (temporarily) print the integer value of the character read, to check if it is what you expect.

    Some additional advice:

    • The correct signature for the main function, using no parameters, is int main(void).
    • The printf statement that prints the result of division specifies floating point numbers, however, the variables passed to it are of the int type. There are casts on the previous lines, but the resulting values are still stored in ints.
    • A floating point complex type does exist in C99.