Search code examples
cgetchar

Problems in C code


I am trying to make a simple calculator in Turbo C(I have my own reasons to why I use Turbo C now)

#include <stdio.h>
#define P printf
int loop[] = {1, 1, 1, 1};
int num;
char input[64];
void main()
{
    int num1, num2;
    char x, y;
    while(loop[0] == 1)
    {
        clrscr();

        P("Hello!, This simple calculator will help you compute 2 numbers.");
        P("\nPress the corresponding key to choose the operation you will use.");
        P("\n\nA - (A)ddition");
        P("\nS - (S)ubtraction");
        P("\nM - (M)ultiplication");
        P("\nD - (D)ivision");
        P("\n\nAnswer: ");

        while(loop[1] == 1)
        {
            x = getchar();

            if(tolower(x) == 'a')
            {
                P("\nYou have chosen addition.");
                num1 = askForNumber("\n\nEnter 1st number: ");
                num2 = askForNumber("\nEnter 2nd number: ");
                P("\n\n%d + %d = %d", num1, num2, num1+num2);
            }
            else if(tolower(x) == 's')
            {
                P("\nYou have chosen subtraction.");
                num1 = askForNumber("\n\nEnter 1st number: ");
                num2 = askForNumber("\nEnter 2nd number: ");
                P("\n\n%d - %d = %d", num1, num2, num1-num2);
            }
            else if(tolower(x) == 'm')
            {
                P("\nYou have chosen multiplication.");
                num1 = askForNumber("\n\nEnter 1st number: ");
                num2 = askForNumber("\nEnter 2nd number: ");
                P("\n\n%d * %d = %d", num1, num2, num1*num2);
            }
            else if(tolower(x) == 'd')
            {
                P("\nYou have chosen division.");
                num1 = askForNumber("\n\nEnter 1st number: ");
                num2 = askForNumber("\nEnter 2nd number: ");
                P("\n\n%g* %g = %.2f", (float)num1, (float)num2, (float)(num1/num2));
            }
            else
            {
                P("\nYou have entered an invalid character!");
                P("\n\nAnswer: ");
                continue;
            }

            while(loop[2] == 1)
            {
                P("\n\nDo you want to do another calculation? Y/N: ");
                y = getchar();
                if(tolower(y) == 'y' || tolower(y) == 'n')
                {
                    loop[2] = 0;
                }
                else
                {
                    P("\nYou have entered an invalid character.");
                    continue;
                }
            }

            loop[1] = 0;
        }

        if(tolower(y) == 'y')
        {
            continue;
        }
        if(tolower(y) == 'n')
        {
            loop[0] = 0;
        }
    }
}

int askForNumber(const char *string)
{
    P("%s", string);
    while(loop[3] == 1)
    {
        fgets(input, (sizeof(input)/sizeof(input[0]))-1, stdin);
        if(sscanf(input, "%d", &num) != 1)
        {
            num = 0;
            P("Invalid number!");
            continue;
        }
        return num;
    }
}

I have these bugs:

  1. After I finish a calculation, and press 'Y', it clears the screen non-stop.

  2. After "Enter 1st number: ", the "Invalid number" shows up once even though I haven't typed anything yet(but i can still input a number and it will be saved to 'num1', "Invalid number just bugs me".

  3. At the top where I am to input 'a' or 's' or 'm' or 'd' to choose an operation, if I put some letter except for that above, i get this

OUTPUT:

Answer: o

You have entered an invalid character!
Answer:

You have entered an invalid character!
Answer:

the error shows up twice, but i only typed once.


Solution

  • When there are no characters in the input buffer, the getchar function blocks until the return key is pressed. All keys, including return, are stored in the input buffer, then getchar returns the first character in the buffer. The next call to getchar will immediately return the next character in the buffer.

    So if you press 'y' then return, the first call to getchar returns the 'y' character, and the next returns a newline character, i.e. the return key.

    You need to flush the input buffer each time you use getchar to skip over the newline:

    do {
        c = getchar();
    } while (c == '\n');