2

I am new to C and I am trying to make a simple calculator

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

int main() {
    int firstNumber, secondNumber, answer;
    char mathSign[20];

    printf("Enter first number \n");
    scanf("%d", &firstNumber);

    printf("Enter sign \n a - Add \n s = Subtract \n m - Multiply \n d - Divide \n");
    scanf("%s", mathSign);

    printf("Enter second number \n");
    scanf("%d", &secondNumber);

    if (mathSign == 'a') {
        answer = firstNumber + secondNumber;
    } else if (mathSign == 's') {
        answer = firstNumber - secondNumber;
    } else if (mathSign == 'm') {
        answer = firstNumber * secondNumber;
    } else if (mathSign == 'd') {
        answer = firstNumber / secondNumber;
    }

    printf("Your answer is %d", answer);

    return 0;
}

The answer always ends up as 52 for some reason. Should I make the integers doubles?

chqrlie
  • 114,102
  • 10
  • 108
  • 170
  • 1
    `mathSign` is an *array*, i.e. a string. You compare strings using [`strcmp`](http://en.cppreference.com/w/c/string/byte/strcmp). Or you can compare the first *character* of `mathSign` with another character. – Some programmer dude Jul 16 '17 at 11:16
  • Also, what if the user enters some input for `mathSign` that's not valid? You need to handle that case as well (and it's this case that happens with your invalid comparisons now). – Some programmer dude Jul 16 '17 at 11:17
  • 1
    Why are using a char array? You can simply use char here – Shubham Agrawal Jul 16 '17 at 11:18
  • 1
    you should read the warnings the compiler issues. – Jean-François Fabre Jul 16 '17 at 11:19
  • Lastly, please take some time to read [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) by Eric Lippert. If you stepped through the code in a debugger the problem would have been quite obvious. – Some programmer dude Jul 16 '17 at 11:19
  • 1
    use a switch case using the first character of the string for instance – Jean-François Fabre Jul 16 '17 at 11:19
  • @Jean-François Fabre mayme he does not know about switch yet. Let the guy program the way he wants. – 0___________ Jul 16 '17 at 11:23
  • I suggest using a char buffer instead of a string buffer, since the input is a single character. – nounoursnoir Jul 16 '17 at 11:28
  • @nounoursnoir Is there any difference between the two, as far as C is concerned? – WhiteSword Jul 16 '17 at 11:36
  • In future, if you ever want to use `strcmp()` do read this post, [return value from strcmp](https://stackoverflow.com/questions/34824838/what-does-strcmp-exactly-return-in-c/34824887#34824887) – WhiteSword Jul 16 '17 at 11:38
  • "The answer to the ultimate question of life, the universe and everything is 42." :) – sg7 Jul 16 '17 at 11:45
  • @ManjinderSinghHanjra in such little program, the performance will be almost the same. But every learner should get used to do good practice things, like for example choosing options that cost less memory than others, or learning to make subtle differences that could save a lot of process time in bigger programs. It's all about knowing C better. That, in my mind, is how you learn to write decent C. – nounoursnoir Jul 16 '17 at 13:34
  • @nounoursnoir no doubt, you are right about it. But char buffer, and char array buffer which you are referring as string buffer, aren't the terms same in context of C? – WhiteSword Jul 16 '17 at 13:45
  • 1
    @ManjinderSinghHanjra `char` and `array of char` are two different terms. The first correponds to a single character, and the second corresponds to a sequence of one or more characters (and that's not a string, I was wrong). – nounoursnoir Jul 17 '17 at 01:00
  • @nounoursnoir May be I have misinterpreted your comment. Obviously, `char` & `char []` are different terms. By the way, a buffer is a chunk of bytes, and a char generally corresponds to 1 byte, so we can't interchange `char` & `char buffer`, the latter term is more suitable to be called as `char array`. – WhiteSword Jul 17 '17 at 02:05
  • @ManjinderSinghHanjra ah ok to me buffer is the name that we give to a memory location in which we store an input (or other thing that must be stored somewhere before being used) – nounoursnoir Jul 17 '17 at 14:48

3 Answers3

1

Try this code. This should work. Also, this one will be the optimized one.

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

int main() {
    int firstNumber, secondNumber, answer;
    char mathSign;

    printf("1.Enter first number \n");
    scanf("%d", &firstNumber);

    printf("Enter sign \n a - Add \n s = Subtract \n m - Multiply \n d - Divide \n");
    scanf(" %c", &mathSign);

    printf("Enter second number \n");
    scanf("%d", &secondNumber);

    switch (tolower(mathSign)) {
    case 'a':
        answer = firstNumber + secondNumber;
        break;
    case 's':
        answer = firstNumber - secondNumber;
        break;
    case 'm':
        answer = firstNumber * secondNumber;
        break;
    case 'd':
        answer = firstNumber / secondNumber;
        break;
    default:
        printf("Invalid Choice");
        break;
    }

    printf("Your answer is %d", answer);
    return 0;
}
0

When you use just a mathSign it is a pointer to an array. To access first element you have to use mathSign[0].

Alternatively, since you are interested only in one character for a sign you can declare char mathSign instead of char mathSign[20] then read sign character using scanf(" %c", mathSign); In this case the comparison mathSign == 'a would be correct.

sg7
  • 5,668
  • 2
  • 31
  • 39
  • Skipping the pending white space before the operator is necessary, otherwise you will likely read a pending newline into `mathSign`. For this, you can change the format string to `scanf(" %c", mathSign)` – chqrlie Jul 16 '17 at 12:03
0

You test mathSign == 'a' but mathSign is an array, so you should write mathSign[0] == 'a'. The compiler should have produced a warning. You should not ignore these warnings, they indicate problems that are often real bugs. You can get more useful diagnostics by raising the warning level: gcc -Wall -W -Werror or clang -Weverything -Werror...

Note that scanf("%s", mathSign); will cause a buffer overflow if the user types a word longer than 19 characters. You should protect the destination array with:

scanf("%19s", mathSign);

Furthermore, you should check that the conversion succeeds, otherwise you may have undefined behavior if the input cannot be converted and you use the values that are still uninitialized.

You could use " %c" to read a single character and use the classic operators for a more readability. Note the space before the %c: it lets scanf() skip pending white space characters, such as the newline from the previous response.

Here is a modified version:

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

int main(void) {
    int firstNumber, secondNumber, answer;
    char mathSign;

    printf("Enter first number: ");
    if (scanf("%d", &firstNumber) != 1)
        return 1;

    printf("Enter operation\n + - Add\n - = Subtract\n * - Multiply\n / - Divide\n");
    if (scanf(" %c", &mathSign) != 1)
        return 1;

    printf("Enter second number: ");
    if (scanf("%d", &secondNumber) != 1)
        return 1;

    if (mathSign == '+') {
        answer = firstNumber + secondNumber;
    } else if (mathSign == '-') {
        answer = firstNumber - secondNumber;
    } else if (mathSign == '*') {
        answer = firstNumber * secondNumber;
    } else if (mathSign == '/') {
        answer = firstNumber / secondNumber;
    } else {
        printf("unsupported operation: %c\n", mathSign);
        return 1;
    }

    printf("Your answer is %d\n", answer);

    return 0;
}

You can further simplify the program with a switch statement:

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

int main(void) {
    int firstNumber, secondNumber, answer;
    char mathSign;

    printf("Enter a simple expression: ");
    if (scanf("%i %c%i", &firstNumber, &mathSign, &secondNumber) != 3)
        return 1;

    switch (mathSign) {
      case '+': answer = firstNumber + secondNumber; break;
      case '-': answer = firstNumber - secondNumber; break;
      case '*': answer = firstNumber * secondNumber; break;
      case '/': answer = firstNumber / secondNumber; break;
      case '%': answer = firstNumber % secondNumber; break;
      default: 
        printf("unsupported operation: %c\n", mathSign);
        return 1;
    }
    printf("the result is %d\n", answer);
    return 0;
}
chqrlie
  • 114,102
  • 10
  • 108
  • 170
  • Thank you! But whenever i do not make it an array, it skips the whole part that asks for the mathsSign – Anton Truong Jul 16 '17 at 12:01
  • @AntonTruong: `char mathSign; scanf("%c", &mathSign);` indeed has a problem: skipping the pending white space before the operator is necessary, otherwise you will likely read a pending newline into `mathSign`. For this, you can change the format string to `scanf(" %c", mathSign)`. – chqrlie Jul 16 '17 at 12:05