You probably do not need to store the whole file in memory, but instead read one line at a time, evaluate it and print the result:
- define a buffer long enough for a line of input
- define an array of
int
to use as an RPN stack
- in a loop, read each line of input
in a nested loop, using strtok
, parse tokens:
- if the token is a number, push its value onto the stack
- if the token is an operator, perform this operation between the top 2 elements of the stack and store the result onto the stack after popping them.
at the end of the line, print the value at the top of the stack
You want to perform simple checks for stack overflow and underflow.
Here is a sample implementation:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char buffer[256];
int stack[sizeof(buffer) / 2]; // no need for stack overflow check
int i, sp, tos;
while (fgets(buffer, sizeof buffer, stdin)) {
char *p = buffer, *token, *q;
sp = -1;
stack[++sp] = 1;
stack[++sp] = 1;
while ((token = strtok(p, " \t\r\n")) != NULL) {
p = NULL;
tos = stack[sp];
if (!strcmp(token, "+")) {
stack[--sp] += tos;
} else
if (!strcmp(token, "-")) {
stack[--sp] -= tos;
} else
if (!strcmp(token, "*")) {
stack[--sp] *= tos;
} else
if (!strcmp(token, "/")) {
if (tos == 0 || (tos == -1 && stack[sp - 1] == INT_MAX)) {
printf("division overflow\n");
break;
}
stack[--sp] /= tos;
} else
if (!strcmp(token, "%")) {
if (tos == 0 || (tos == -1 && stack[sp - 1] == INT_MAX)) {
printf("division overflow\n");
break;
}
stack[--sp] %= tos;
} else {
tos = strtol(token, &q, 0);
if (q == token || *q != '\0') {
printf("invalid token: %s\n", token);
break;
}
stack[++sp] = tos;
}
if (sp < 2) {
printf("stack underflow for %s\n", token);
break;
}
}
if (token == NULL) {
for (i = 2; i <= sp; i++) {
printf("%d%c", stack[i], i == sp ? '\n' : ' ');
}
}
}
return 0;
}
Input:
12 3 /
2 3 -
3 4 *
1 2 4 + - 5 * 7 /
Output:
4
-1
12
-3