After solving the exercise 5-10 in the K&R:
Write the program expr, which evaluates a reverse Polish expression from the command line, where each operator or operand is a separate argument. For example, expr 2 3 4 + * evaluates 2*(3+4).
there appears to be the problem in expressions with '*' character, even basic ones like: 2 2 *. For some strange reason, '*' is not placed into the operator array, while all other characters like '+', '-', '/' normally are. I've isolated the part of the code (while loop) which appears to be wrong. Push function is from Chapter 4 and it is only necessary to compile the code.
#include <stdio.h>
void push(double f);
main(int argc, char *argv[])
{
int a = 0;
int b;
char operator[10];
while (--argc > 0) {
if (isdigit(*argv[argc]))
push(atof(argv[argc]));
else if (*argv[argc]=='+' || *argv[argc]=='-' || *argv[argc]=='*' || *argv[argc]=='/')
operator[a++] = *argv[argc];
}
for (b = 0; b < a; b++)
printf("%c", operator[b]);
printf("\n");
return 0;
}
#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
/* push: push f onto value stack */
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
Output
[user@machine Desktop]$ ./prog + +
++
[user@machine Desktop]$ ./prog *
[user@machine Desktop]$ ./prog * *
[user@machine Desktop]$ ./prog + / * -
-/+
Your shell is interpreting *
and expanding it. To the shell, '*' means "match all text", which is why commands like ls *.c
work. Type echo *
and you'll see what I mean. Put your arguments in single quotes to prevent the shell from interpreting them.
E.g.,
./prog '*'
./prog 2 2 '*'
./prog '2' '2' '*'
Note that if you put all arguments inside quotes, that entire thing will be given to your program as one entry in argv
, which might not be what you want.
E.g., this command will fill argv[1]
with the text 2 2 *
, instead of breaking it up into 2
, 2
, and *
in argv[1]
, argv[2]
, and argv[3]
.
./prog '2 2 *'
You can also escape individual characters that need escaping with backslash instead of quotes. Your program will get a literal *
if you tell the shell \*
.
E.g.,
./prog 2 2 \*
This pattern matching is commonly called globbing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With