传递 `*` 时命令行参数数量不正确

6
我正在编写一个关于逆波兰表达式的C程序,该程序通过命令行参数获取其操作数和运算符。但是当出现乘法运算符'*'时,事情就出了问题,我不知道原因。
以下是调试小程序。

test.c

int main(int argc, char **argv)
{
    printf("%d\n", argc);
    return 0;
}

//   run case           result
    ./test a b            3
    ./test *              66

那么为什么使用“*”参数会导致错误的结果?

2
* 有特殊含义。 - Maroun
1
Shell会将*扩展为目录中所有可见的文件,你可以将其视为乘法运算符'x'。 - hetepeperfan
2个回答

11

*会进行shell通配符扩展,因此它将展开为当前目录中的所有文件,这些文件将成为程序的参数,当前目录下有65个文件。如果运行echo *,你可以看到发生了什么。

你需要用单引号引起来*,例如./test '*'(双引号也可以),这将防止shell扩展*。在这种情况下,程序会接收到一个带有单引号的*,shell会将其删除。

如果您想要计算表达式,可以执行以下操作:

./test 3 2 '*'

在这种情况下,您的程序会接收到3个额外的参数,分别为argv[1]3argv[2]2argv[3]*

或者您可以这样做:

./test '3 2 *'
在这种情况下,你的程序会接收到1个额外的参数,argv[1] 将是字符串 3 2 *

@Bathsheba,没错! - Bin
意思是我必须将“”解析为“”,-_- - Bin
3
不需要把 '*' 解析成 *。这是由 Shell 将 * 转换为当前目录中的文件列表,将 '*'(或 "*")转换为 * 单个字符。因此,如果从 Shell 给程序传递 '*',则程序将只接收一个参数,其中包含不带引号的 * 字符。请注意,这些变化是由 Shell 在传递参数之前发生的。 - Shahbaz
1
为了使输入尽可能干净,请使用例如 echo '1 2 * 3 *' | xargs ./test - 这与 ./test '1 2 * 3 *' 一样干净,但也可以正确填充 argv 数组。 - anatolyg

8
你的命令行解释器把*当做通配符处理。它可能包含了当前目录下的每一个文件,对于你的情况来说大约有60个文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接