For some reason, when I execute this program with the following expression 12 12 * 66 +
it returns an invalid and negative answer -46
. I'm curious as is to what is going wrong, and would like to fix it asap.
#include <stdio.h>
#include <stdlib.h>
#include "usefunc.h"
#define OFFSET '0'
/*
* I only use one constant.....I really don't need another. and in fact took more
* memory to use the constant than without. several bytes!!
*/
/*
* for this program, I found a library that contained C implementations
* of a stack. I thought I'd use it, since I understand everything it
* does fully. you can quiz me on the stuff I did not write, if you want.
*/
//setting up the stack
typedef char stackElementT;
//it's a struct, so it can contain several elements
//like maxSize, top, and of course the contents
//let's call it stackT
typedef struct {
stackElementT *contents;
int maxSize;
int top;
int min2;
} stackT;
//allocates the memory for the size passed to the function
//then checks if there's enough memory
//then sets the size to maxSize, `top` to -1 (empty), and contents to newContents
void StackInit(stackT *stackP, int maxSize) {
stackElementT *newContents;
newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize);
if (newContents == NULL) {
fprintf(stderr, "Not enough memory.\n");
exit(1);
}
stackP->contents = newContents;
stackP->maxSize = maxSize;
stackP->top = -1; //empty...
}
//frees the allocated memory
//sets it all to NULL
//sets the size to 0, all that good stuff
void StackDestroy(stackT *stackP) {
free(stackP->contents);
stackP->contents = NULL;
stackP->maxSize = 0;
stackP->top = -1; //empty
}
//just referencing top
int StackIsEmpty(stackT *stackP) {
return stackP->top < 0;
}
//and top again
int StackIsFull(stackT *stackP) {
return stackP->top >= stackP->maxSize-1;
}
//and top once more
//adds one to the top of the stack by first incrementing the top, and then adding the element in at the top
//unless of course it's full
void StackPush(stackT *stackP, stackElementT element) {
if(StackIsFull(stackP)) {
fprintf(stderr, "Can't push element: stack is full.\n");
exit(1);
}
stackP->contents[++stackP->top] = element;
}
//pops it, and then subsequently updates `top`
//unless of course it's empty
stackElementT StackPop(stackT *stackP) {
if(StackIsEmpty(stackP)) {
fprintf(stderr, "Can't pop element: stack is empty.\n");
exit(1);
}
return stackP->contents[stackP->top--];
}
/*
* my work starts here:
*/
double eval(double x, double y, char operand) {
switch(operand) {
case '+': return x+y;
case '-': return x-y;
case '/': return x/y;
case '*': return x*y;
case '^': return pow(x, y);
}
}
int is_operand(char x) {
switch(x) {
case '+':
case '-':
case '/':
case '*':
case '^': return 1;
default: return 0;
}
}
double postfix(char* expr, int length) {
//counter, and two temporary variables
int i;
double temp = 0, temp2;
//and of course the stack
stackT stack;
//lotta frames...
StackInit(&stack, 1000);
//loops through string input. as of now, it only works with one digit numbers :(
for (i = 0; i < length; i++) {
//printf("%d : %c\n", expr[i], expr[i]);
//is it a number? yes? push the decimal version of it to the stack
if ((expr[i] >= '0') && (expr[i] <= '9')) {
//printf("temp=%f\n", temp);
temp *= 10;
temp += expr[i]-OFFSET;
//printf("temp=%f\n", temp);
}
else if (expr[i] == ' ') {
StackPush(&stack, temp);
temp = 0;
}
//no?
else {
//switch-case statement, easy peasy
switch (expr[i]) {
//operations checking
case '+': {
temp = StackPop(&stack);
temp2 = StackPop(&stack);
//printf("%f+%f\n", temp2, temp);
StackPush(&stack, temp2+temp);
temp = temp2+temp;
}
break;
case '-': {
temp = StackPop(&stack);
temp2 = StackPop(&stack);
//printf("%f-%f\n", temp2, temp);
StackPush(&stack, temp2-temp);
temp = temp2-temp;
}
break;
case '/': {
temp = StackPop(&stack);
temp2 = StackPop(&stack);
//printf("%f/%f\n", temp2, temp);
StackPush(&stack, temp2/temp);
temp = temp2/temp;
}
break;
case '*': {
temp = StackPop(&stack);
temp2 = StackPop(&stack);
//printf("%f*%f\n", temp2, temp);
StackPush(&stack, temp2*temp);
temp = temp2*temp;
}
break;
//POWERS?!?! whoa. this wasn't required.
case '^': {
temp = StackPop(&stack);
temp2 = StackPop(&stack);
//printf("%f^%f\n", temp2, temp);
StackPush(&stack, pow(temp2, temp));
temp = pow(temp2, temp);
}
default:
break;
}
}
}
//just giving the number it pushed
return StackPop(&stack);
}
int main() {
//so many counters...!
//almost a shell
while (1) {
//prompt
printf("postfix expression:\t");
//getLine
char *expr = GetLine();
//aaaaaaaaaand evaluate it
printf("%.0f\n\n", postfix(expr, strlen(expr)));
}
}