【问题标题】:command line arguments argv and argc命令行参数 argv 和 argc
【发布时间】:2020-01-23 22:49:05
【问题描述】:

我知道argc 计算参数的数量,argv 接受参数,但这是我可以确定来自argv 的参数是否以某种格式输入的方式,如括号中而不是插入语。比如./a.out "Hello Word"./a.out Hello World

【问题讨论】:

  • 第一个将只有一个参数。第二个是两个。特定的外壳可能会添加它自己的怪癖。
  • 在大多数 shell 终端(如 bash)上,引号用于将包含空格(如空格和制表符,通常用于分隔 argv 参数)的参数组合在一起(如在单个 argv 中)。特殊字符通常不保存在 argv 中。如果要将这些特殊字符用作普通字符,则需要使用转义字符`\`。
  • 如果您发现其中一个参数包含空格,那么它肯定是在括号之间传递的
  • 这是早期 Unix shell 所犯的一个根本性错误,不幸的是,为了兼容性必须永远存在。一个程序不可能在 shell 以多种方式弄乱它之前获得它的命令行。这应该是一个库调用,而不是 shell 的永久功能。

标签: c arguments argv argc


【解决方案1】:

是的,不是的。基本上,做到这一点的唯一方法是与strcmp 之类的函数进行字符串比较。但是,使问题复杂化的一件事是,您使用的 shell 可能会在您的程序有机会看到引号之前删除它们。更糟糕的是,如何处理这取决于 shell,所以对一个 shell 有效的方法可能对另一个 shell 失败。 Posix shell(sh、bash、ksh 等)处理引号的方式相同,但不提供任何检测方式。

这个程序:

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("Number of arguments: %d\n", argc);
    for(int i=0; i<argc; i++)
        printf("Argument %d: %s\n", i, argv[i]);
}

在使用 shell bash 时,将这个输出作为一个星号作为参数:

/tmp/test$ ./a.out *
Number of arguments: 3
Argument 0: ./a.out
Argument 1: a.out
Argument 2: main.c

这是因为* 被shell 扩展为当前目录中的所有文件。引号通常将原本会被视为两个不同论点的事物组合在一起。如果您想将引号传递给 bash,您可以对其进行转义。

/tmp/test$ ./a.out "Hello world"
Number of arguments: 2
Argument 0: ./a.out
Argument 1: Hello world

/tmp/test$ ./a.out \"Hello world\"
Number of arguments: 3
Argument 0: ./a.out
Argument 1: "Hello
Argument 2: world"

所以很遗憾,答案是否定的。没有通用的方法可以做到这一点。一些 shell 可能会提供执行此操作的工具,但无法保证这一点,即使提供,也没有标准的方法来执行此操作。

【讨论】:

  • 每个 Posix shell 都以相同的方式处理引用的参数。当然,cmd 不是 Posix shell,但在类 unix 系统上,您可以期待相同的行为。
  • @rici 但据我所知,没有办法检测到它?对吗?
  • 没有办法检测到。没有外壳提供这样的机制。它不依赖于外壳,在 Posix 环境中。当然,Windows 是不同的。
猜你喜欢
  • 2020-05-19
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 2016-06-11
  • 2013-06-13
  • 2020-11-15
相关资源
最近更新 更多