After seeing lots of “simple calculator” post/help requests from those I like to refer to “incompetents”, I decided to waste a little time and write something slightly more advanced. It’s nothing special; It handles brackets but not operator precedence. All evaluation is performed left to right.
Before I continue, I’d like to explain why I refer to those as “incompetents”. I’d love to write a lengthy, patriotic speech about it, but the long story is short: They can obviously read as they are coming to forums to ask questions, yet they obviously haven’t bothered reading a book because all of the books deal with these problems. … That or they’re idiots.
I didn’t get where I am today by ignoring books, and I’m not trying to brag… I don’t consider myself advanced by any means. If you want to learn, take control of your own learning. Don’t let other idiots mislead or misinform you.
/* (c) Sebastian Ramadan 2011, all rights reserved */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct operation {
int operat0r;
int x;
int y;
};
struct operation *resize(struct operation *alloc, unsigned int capacity);
int calc(char *str);
int main(void) {
char *problems[] = {
"3 * 2 + 8 / 4",
"3 * 2 + (8 / 4)",
"3 * (2 + 8 ) / 4",
"3 * (2 + 8 / 4)",
"(3 * 2 + 8 ) / 4",
"(3 * 2) + 8 / 4",
"(3 * 2) + (8 / 4)",
"(3 * 2 + 8 / 4)"
};
for (int x = 0; x < sizeof (problems) / sizeof (*problems); x++) {
printf("%s = %d\n", problems[x], calc(problems[x]));
}
return 0;
}
struct operation *resize(struct operation *alloc, unsigned int capacity) {
struct operation *temp = (struct operation *) realloc(alloc, sizeof (struct operation) * capacity);
if (temp == NULL) {
fprintf(stderr, "Error in realloc.\n");
exit(EXIT_FAILURE);
}
return temp;
}
int calc(char *str) {
int operat0r = '\0', x = 0, y = 0, *operand;
struct operation *stack = NULL;
unsigned int level = 0, capacity = 0;
operand = &x;
stack = resize(stack, ++capacity);
while (*str != '\0') {
switch (*str) {
case '(':
stack[level ].operat0r = operat0r;
stack[level ].x = x;
stack[level++].y = y;
operat0r = '\0', x = 0, y = 0;
str++;
break;
case ')':
if (level == 0) {
fprintf(stderr, "Error: Too many closing brackets...\n");
exit(EXIT_FAILURE);
}
operand = stack[--level].operat0r == '\0' ? &stack[level].x : &stack[level].y;
*operand = operat0r == '+' ? x + y :
operat0r == '-' ? x - y :
operat0r == '*' ? x * y :
operat0r == '/' ? x / y :
x;
operat0r = stack[level].operat0r;
x = stack[level].x;
y = stack[level].y;
str++;
case '\0':
x = operat0r == '+' ? x + y :
operat0r == '-' ? x - y :
operat0r == '*' ? x * y :
operat0r == '/' ? x / y :
x;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
int temp;
if (operat0r == '\0' && sscanf(str, "%d%n", &x, &temp) != 1 || sscanf(str, "%d%n", &y, &temp) != 1) {
fprintf(stderr, "Error: Invalid operand.\n");
exit(EXIT_FAILURE);
}
else if (operat0r != '\0') {
x = operat0r == '+' ? x + y :
operat0r == '-' ? x - y :
operat0r == '*' ? x * y :
operat0r == '/' ? x / y :
x;
y = 0;
operat0r = '\0';
}
str += temp;
break;
case '+':
case '-':
case '*':
case '/':
operat0r = *str;
case ' ':
str++;
default:
break;
};
}
if (level > 0) {
fprintf(stderr, "Error: Too many opening brackets...\n");
exit(EXIT_FAILURE);
}
return x;
}