0
votes

I have to write a simple calculator in C, that only uses getchar/putchar. I need to echo the user input, and then perform the mathematical operation (only need to use +, /, %, *, and -). Right now, I only care about what I'm doing wrong, as far as storing the values into my input variables. The rest of the program should be fairly easy to do myself.

In my while loop, I tried to be careful with nesting if/else's (mainly for error-checking purposes) only inside my "else if's". I want my loop to ignore spaces, and then assign the number, math operator, and other number into input1, input2, and input3, respectively. Right now, if I input something like "55 * 66", I am returned something like "*0".

Thanks for looking.

UPDATE (3/22/2014): I'm getting a little bit closer. My problem right now is that the program will only work when I input one space after each number and operand (i.e. "2 + 4" works, but anything without spaces, or with more than one space, does not). I also didn't quite get how to putchar the numbers to output them. I used printf so I could at least have a working program, in the mean time. Thanks.

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

int add(int input1,char operand, int input2);
int subtract(int input1,char operand, int input2);
int mod(int input1,char operand, int input2);
int multiply(int input1,char operand, int input2);
int divide(int input1,char operand, int input2);

int main()
{

    int answer = 0;
    int ch = 0;
    int input1 = 0;
    char operand = 0;
    int input2 = 0;
    int function = 0;

    printf("\nPlease enter a calculation to be made.\n");

    while (((ch = getchar()) != ' ') && (ch != '\n')){

    if (ch == '-') {
        printf("\nError: no negatives allowed.\n");
    }

    else if (!isdigit(ch)){
    printf("\nError: number not inputted (first number).\n");
    }

    else {
        input1 = (input1 * 10) + (ch - '0');
        }
}

    while (((ch = getchar()) != ' ') && (ch != '\n')){

        switch(ch){

        case '+':
        operand = '+';
        break;

        case '-':
        operand = '-';
        break;

        case '%':
        operand = '%';
        break;

        case '*':
        operand = '*';
        break;

        case '/':
        operand = '/';
        break;

        default:
        printf("Error: input is not one of the allowed operands.");
        break;

        }

    }

    while (((ch = getchar()) != ' ') && (ch != '\n')){


    if (ch == '-') {
        printf("\nError: no negatives allowed.\n");
    }

    else if (!isdigit(ch)){
    printf("\nError: number not inputted (second number).\n");
    }

    else {
        input2 = (input2 * 10) + (ch - '0');
        }
}

printf("%d", input1);
putchar(' ');

printf("%c", operand);
putchar(' ');

printf("%d", input2);

putchar(' ');
putchar('=');
putchar(' ');

if (operand == '+'){
answer = add(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '-'){
answer = subtract(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '%'){
answer = mod(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '*'){
answer = multiply(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '/'){
answer = divide(input1, operand, input2);
printf("%d", answer);
}

    return 0;
}

int add(int input1,char operand, int input2){

return input1 + input2;

}

int subtract(int input1,char operand, int input2){

return input1 - input2;

}

int mod(int input1,char operand, int input2){

return input1 % input2;

}

int multiply(int input1,char operand, int input2){

return input1 * input2;

}

int divide(int input1,char operand, int input2){

return input1/input2;

}
1
You have two cases that test for isdigit(ch). The first one does nothing, and will always be taken in favor of the second one which stores ch in input3. - pat
You can use isspace to check for whitespace. Also, what are you hoping to accomplish by comparing ch >= 0 after it has been established that ch is a digit? Don't forget that ch is the ASCII value for a digit character, not the numeric value of the number itself. - pat
ch >= 0 will not test if the number is greater than or equal to 0. It will test if the encoding for the character entered is >= 0. Not quite what you want. Maybe you meant ch >= '0', but that's not of much use either. Just go with isdigit(). Remember that if the user entered a negative number, you will first read a -. - Filipe Gonçalves
Thanks for the response - Regarding checking whether ch >= 0, part of this code is that I want to check for, and exclude, negative numbers. I should have made that clear. I also added "input1 = ch;" in the first else if, which I'm not sure why it wasn't there. I'm still having issues, though. - user2411290
What you have in your hand is the ASCII value of a single digit character, not a signed multi-digit integer. You are going to have to write a more complicated parser to read an optional '-' followed by multiple digit characters, convert each digit from ASCII to the actual numeric value, and merge them into a single integer in some number base (typically, we use base 10!). - pat

1 Answers

1
votes

The simplest thing to do would be to parse each piece of the expression in sequence:

int main(int argc, char **argv)
{
    int ch;
    int a;
    char op;
    int b;
    int negate;

    // start with a character of lookahead
    ch = getchar();

    // skip leading spaces
    while (ch != EOF && isspace(ch) && ch != '\n') ch = getchar();

    // read A operand
    a = 0;
    if ((negative = (ch == '-'))) ch = getchar();
    if (ch == EOF || !isdigit(ch)) {
        // error, expecting a digit or '-' here
    }
    do {
        // convert digit from ASCII, and "shift" into accumulator
        a = (a * 10) + (ch - '0');
        ch = getchar();
    }
    while (ch != EOF && isdigit(ch));
    if (negative) a = -a;

    // skip spaces
    while (ch != EOF && isspace(ch) && ch != '\n') ch = getchar();

    // read operator
    if (ch == EOF || (ch != '+' && ch != '-' && ...)) {
        // error, expecting an operator
    }
    op = ch;
    ch = getchar();

and so on...