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;
}
© 2011 GeekyCode proudly hosted by GeekShells. Suffusion theme by Sayontan Sinha