Amazing C program output when using "*" for multiplication

After solving exercise 5-10 in K&R:

Write a program expr that evaluates the reverse polish expression from the command line, where each operator or operand is a separate argument. For example, the expression 2 3 4 + * evaluates to 2 * (3 + 4).

there seems to be a problem in expressions with "*", even basic ones such as: 2 2 *. For some strange reason, "*" does not fit into the operator array , while all other characters such as "+", "-", "/" are usually. I have highlighted the part of the code (while loop) that seems to be wrong. The Push function is from Chapter 4 and is only needed 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 + / * -
-/+

      

+3


source to share


1 answer


The shell interprets *

and expands it. For the shell, "*" means "match all text", so commands like ls *.c

. Enter echo *

and you will understand what I mean. Put your arguments in single quotes to prevent shell interpretation.

eg.

./prog '*'
./prog 2 2 '*'
./prog '2' '2' '*'

      

Note that if you put all the arguments inside quotes, they will all be passed to your program as a single entry in argv

, which may not be what you want.

For example, this command will fill with argv[1]

text 2 2 *

instead of breaking it into 2

, 2

and *

into argv[1]

, argv[2]

and argv[3]

.



./prog '2 2 *'

      

You can also avoid individual characters that require escaping with a backslash instead of quotation marks. Your program will get a literal *

if you tell the shell \*

.

eg.

./prog 2 2 \*

      

This pattern matching is commonly referred to as globbing .

+11


source







All Articles