#include #include #include #include #include /* The C Programming Language: 2nd Edition * * Exercise 7-5: Rewrite the postfix calculator of Chapter 4 to use scanf * and/or sscanf to do the input and number conversion. * * Notes: * scanf wants allocated memory of some sort, meaning you're either going * to pass it a pointer (with malloc()'d memory) or you're passing a variable * with the unary & (address-of) operator. Failing to use scanf correctly * _will_ create runtime problems! gcc won't tell you what happens without * -Wall and -Wextra, but scanf segfaults by trying to access an uninitialized * pointer. * * Thus there are two ways to use scanf: * * int foo = 0; * scanf("%d", &foo); * // do stuff * * -- or -- * * int *foo = malloc(sizeof(int)); * scanf("%d", foo); * // do stuff * free(foo); * * For the sake of sanity in an easy exercise, I'll be using the former form * since a few values on the stack won't hurt anything. */ #define MAXOP 100 #define MAXVAL 100 #define BUFSIZE 100 void push(double); double pop(void); int sp = 0; // Next free stack position double val[MAXVAL]; // Value stack char buf[BUFSIZE]; // buffer int bufp = 0; // next free position in buf double vars[27]; /* Reverse Polish calculator: * * Binary operations (+-*\) * operand operand operator * * Example: 6 minus 2 in Reverse Polish Notation is "6 2 -" */ int main() { char *c; double a = 0, op2; char s[MAXOP]; char ltr = '\0'; while (scanf("%s%c", s, <r) == 2) { if (sscanf(s, "%lf", &a) == 1) { push(a); } else if (sscanf(s, "%s", buf)) { for (c = buf; *c; c++) { switch (*c) { case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if (op2 != 0.0) { push(pop() / op2); } else { printf("Error: Cannot divide by zero.\n"); } break; default: printf("Error: Unknown command %s\n", s); break; } } if (ltr == '\n') { printf("%.8f\n", pop()); } } } return 0; } void push(double f) { if (sp < MAXVAL) { val[sp++] = f; } else { printf("Error: Stack full. Cannot push %g\n", f); } } double pop(void) { if (sp > 0) { return val[--sp]; } else { printf("Error: Stack empty.\n"); return 0.0; } }