// rpn.c: reverse polish notation calculator #include "stack.h" #include #include #define MAXOPSIZE 20 /* maximum size of operand, operator */ #define NUMBER '0' /* indicates number found */ #define TOOBIG '9' /* indicates string is too big */ int getop(char *dest, int limit); int main() { int type; char input[MAXOPSIZE]; double op2; while ( (type = getop(input, MAXOPSIZE)) != EOF ) { switch ( type ) { case NUMBER: push(atof(input)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); push(pop() - op2); break; case '/': op2 = pop(); if ( op2 == 0.0 ) printf("Divide by zero.\n"); else push(pop() / op2); break; case '=': printf("Top: %f\n", push(pop())); break; case 'c': clear_stack(); break; case TOOBIG: printf("Input too large: '%s'\n", input); break; default: printf("Unknown command: '%c'\n", type); } } // end while } int getop(dest, limit) char *dest; // alternative way to specify argument types int limit; { int i, c; while ( (c = getchar()) == ' ' || c == '\t' || c == '\n' ) ; if ( c != '.' && (c < '0' || c > '9') ) return c; dest[0] = c; for(i = 1; (c = getchar()) >= '0' && c <= '9'; ++i) if ( i < limit ) dest[i] = c; if ( c == '.' ) { // collect fractional portion if ( i < limit ) dest[i] = c; for(i++; (c = getchar()) >= '0' && c <= '9'; ++i) if ( i < limit ) dest[i] = c; } if ( i < limit ) { /* number is ok */ ungetc(c, stdin); dest[i] = '\0'; return NUMBER; } else { /* input is too big; skip rest of line */ while ( c != '\n' && c != EOF ) c = getchar(); dest[limit - 1] = '\0'; return TOOBIG; } }