C程序的奇怪输出时使用“*”乘 [英] Surprising output of a C program when using '*' to multiply

查看:112
本文介绍了C程序的奇怪输出时使用“*”乘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解决运动5-10在K&R之后:

编写程序EXPR,它的命令行,每个运营商或操作数是一个单独的参数计算一个逆波兰前pression。例如,位于expr 2 3 4 + *计算2 *(3 + 4)。

似乎是在与前pressions问题*字符,甚至连基本的像:2 *。对于一些奇怪的原因,'*'没有放入运营商的阵列,而其他所有的字符,如+, - ,/通常都是。我已经分离出的code(while循环),这似乎是错误的一部分。推功能是从第4章,它仅需要编译code

 的#include<&stdio.h中GT;无效的push(双F);主(INT ARGC,CHAR *的argv [])
{
    INT A = 0;
    INT B:
    运营商的char [10];    而(--argc大于0){
        如果(ISDIGIT(* ARGV [ARGC]))
            推(ATOF(ARGV [ARGC]));
        否则,如果(* ARGV [ARGC] =='+'|| *的argv [ARGC] ==' - '|| *的argv [ARGC] =='*'|| *的argv [ARGC] =='/')
            运营商[A ++] = *的argv [ARGC]
    }
    对于(B = 0; B< A; B ++)
        的printf(%C,操作符[B]);
    的printf(\\ n);    返回0;
}VAL堆栈的#define MAXVAL 100 / *最大深度* /INT SP = 0; / *下一个空闲堆栈位置* /
双VAL [MAXVAL] / *值栈* // *推:将F-到值栈* /
空推(双F)
{
    如果(SP< MAXVAL)
        VAL [SP ++] = F;
    其他
        的printf(错误:堆栈满,不能推%G \\ N,F);
}

输出

  [用户@机器的桌面] $ ./prog +
++
[用户名@计算机桌面] $ ./prog *[用户名@计算机桌面] $ ./prog * *[用户名@计算机桌面] $ ./prog + / * -
- / +


解决方案

您外壳间preting * 和扩大它。到了壳,*表示匹配所有文字,这就是为什么像 LS的* .c 工作命令。键入回声* ,你就会明白我的意思。放在单引号的参数prevent从国际$ P $外壳pting他们。

例如,

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

请注意,如果你把的所有的引号内的参数,那整个事情将给予你的程序作为一个条目在的argv ,这可能不是你想要的东西。

比如说,这个命令将填补的argv [1] 的文字 * ,第2,而不是打破它成 2 2 * 的argv [1] 的argv [2] 的argv [3]

  ./ PROG'2 *'

您也可以逃脱需要反斜杠,而不是逃避报价单个字符。你的程序将获得一个文字 * 如果你告诉shell \\ *

例如,

  ./ PROG 2 \\ *。

此模式匹配通常被称为通配符

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.

这篇关于C程序的奇怪输出时使用“*”乘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆