【问题标题】:What does int argc, char *argv[] mean?int argc, char *argv[] 是什么意思?
【发布时间】:2011-03-02 17:43:33
【问题描述】:

在许多 C++ IDE 和编译器中,当它为您生成 main 函数时,它看起来像这样:

int main(int argc, char *argv[])

当我在没有 IDE 的情况下仅使用命令行编译器编写 C++ 代码时,我会键入:

int main()

没有任何参数。这是什么意思,它对我的​​计划至关重要吗?

【问题讨论】:

  • 如果您的程序要忽略命令行参数,那么您编写的内容就可以了。如果您的程序需要处理命令行参数,那么 IDE 做对了。
  • 给黑客的提示:尝试声明 int main(int argc, char* argv[], char* envp[]) 并打印出最后一个参数。 ;)
  • @ulidtko 你教新手在他们的程序中引入漏洞是不好的;)
  • @Gab 简单打印环境变量如何导致漏洞?只是不要将受污染的字符串逐字传递给system() 调用、数据库查询等。像往常一样使用用户输入。
  • @ulidtko 有趣.. 你能解释一下为什么在使用char **envp 参数时不必传递受污染的字符串、数据库查询等吗?

标签: c++ parameters command-line-arguments argv argc


【解决方案1】:

argvargc 是在 C 和 C++ 中将命令行参数传递给 main() 的方式。

argc 将是argv 指向的字符串数。这将(实际上)是 1 加上参数的数量,因为几乎所有的实现都会将程序的名称添加到数组中。

变量按约定命名为argc参数计数)和argv参数向量),但它们可以指定任何有效标识符:@987654329 @ 同样有效。

如果您不打算处理命令行参数,它们也可以完全省略,产生int main()

试试下面的程序:

#include <iostream>

int main(int argc, char** argv) {
    std::cout << "Have " << argc << " arguments:" << std::endl;
    for (int i = 0; i < argc; ++i) {
        std::cout << argv[i] << std::endl;
    }
}

./test a1 b2 c3 运行它会输出

Have 4 arguments:
./test
a1
b2
c3

【讨论】:

  • @Chuck:由于“argv[argc] 的值应为 0”(C++03 §3.6.1/2),argv 不能为空。
  • @Chuck: C(至少 C99)有同样的要求。
  • 我想我应该补充一下,这在大多数系统中都是一样的,尽管它们有时被抽象了。例如,在 Pascal/Delphi/Lazarus 中,你会得到; ParamStr 和 ParamCount(如果我没记错的话)。我的观点是,当您(如果有的话)用其他语言/ose 编写本机应用程序时,很有可能上面定义了供您使用,并且它们在所有支持的系统中完全一样(计数/字符串列表)他们。
  • @EmilVikström 不,这是一个可能导致段错误的严重错误。 *NULL 绝对不等于 NULL
  • 好的。 std::cout &lt;&lt; "Have " &lt;&lt; argc &lt;&lt; " arguments:" &lt;&lt; std::endl; 本质上的意思是:向标准输出发送字符串“Have”,然后发送整数 argc,然后发送字符串“arguments:”,然后执行 this 涉及换行符和其他一些我没有的东西还没想好?
【解决方案2】:

argc 是从命令行传入程序的参数数量,argv 是参数数组。

您可以通过知道参数数量的参数进行循环,例如:

for(int i = 0; i < argc; i++)
{
    // argv[i] is the argument at index i
}

【讨论】:

    【解决方案3】:

    main 的参数代表程序启动时提供给程序的命令行参数。 argc 参数表示命令行参数的数量,char *argv[] 是一个字符串数组(字符指针),表示命令行上提供的各个参数。

    【讨论】:

    • Argv[] 始终将 argv[arg] 作为空指针。并且 Argv[0] 始终是(完整路径)/executableName 作为 nul 终止的字符串
    • @user3629249:不一定; argv[0] 是启动 C 程序的程序给出的 argv[0]。在 Bash 的情况下,它通常(也许总是)是可执行文件的路径名,但 Bash 并不是执行其他程序的唯一程序。尽管有些古怪,但允许使用:char *args[] = { "cat", "/dev/null", "/etc/passwd", 0 }; execv("/bin/ls", args);。在许多系统上,程序看到的 argv[0] 值将是 cat,即使可执行文件是 /bin/ls
    【解决方案4】:

    第一个参数是提供的参数数量,第二个参数是代表这些参数的字符串列表。

    【讨论】:

    • argv[0] 中的第一项是程序名,不是参数
    • @user3629249 程序名称和程序路径。 ;)
    【解决方案5】:

    两个

    int main(int argc, char *argv[]);
    int main();
    

    是 C 或 C++ 程序入口点的合法定义。 Stroustrup: C++ Style and Technique FAQ 详细说明了您的主要功能可能或合法的一些变化。

    【讨论】:

    • 可能想把 void 放在... int main() ==> int main(void)... 为了兼容性和可读性。我不知道是否所有旧版本的 C 都允许 void 函数在声明中具有空参数列表。
    • @dylnmc 这不会带来任何可读性增益,并且在所有 C++ 版本中完全相同。只有在 C 中这确实有区别,但只是在声明中,而不是在定义中。
    • @Ruslan 抱歉,我刚刚学习 C 时发布了这个,我可能已经读到在 C 的早期版本中需要 void。不要引用我的话,我现在知道这是一个有点愚蠢的评论。不过,它不会受到伤害。
    • 如果 argc
    【解决方案6】:

    main 函数可以有两个参数,argcargvargc 是一个整数 (int) 参数,它是传递给程序的参数数量。

    程序名称始终是第一个参数,因此程序至少有一个参数,argc 的最小值将是一个。但是如果一个程序本身有两个参数,那么argc 的值将是三个。

    参数argv指向一个字符串数组,称为参数向量。它是函数参数的一维字符串数组。

    【讨论】:

      【解决方案7】:

      假设您这样运行程序(使用sh 语法):

      myprog arg1 arg2 'arg 3'
      

      如果您将 main 声明为 int main(int argc, char *argv[]),那么(在大多数环境中),您的 main() 将被称为:

      p = { "myprog", "arg1", "arg2", "arg 3", NULL };
      exit(main(4, p));
      

      但是,如果您将 main 声明为 int main(),它将被称为类似

      exit(main());
      

      你没有得到传递的参数。

      另外需要注意的两点:

      1. 这是main 仅有的两个标准强制签名。如果特定平台接受额外的参数或不同的返回类型,那么这是一个扩展,不应在可移植程序中依赖。
      2. *argv[]**argv 完全等价,因此您可以将 int main(int argc, char *argv[]) 写为 int main(int argc, char **argv)

      【讨论】:

      【解决方案8】:
      int main();
      

      这是一个简单的声明。它不能接受任何命令行参数。

      int main(int argc, char* argv[]);
      

      当您的程序必须采用命令行参数时使用此声明。像这样运行时:

      myprogram arg1 arg2 arg3
      

      argc 或 Argument Count 将设置为 4(四个参数),argv 或 Argument Vectors 将填充指向“myprogram”、“arg1”、“arg2”和“arg3”。 程序调用 (myprogram) 包含在参数中!

      或者,您可以使用:

      int main(int argc, char** argv);
      

      这也是有效的。

      还有一个参数可以添加:

      int main (int argc, char *argv[], char *envp[])
      

      envp 参数还包含环境变量。每个条目都遵循以下格式:

      VARIABLENAME=VariableValue
      

      像这样:

      SHELL=/bin/bash    
      

      环境变量列表以空值结尾。

      重要提示:不要在对system() 的调用中直接使用任何argvenvp 值!这是一个巨大的安全漏洞,因为恶意用户可以将环境变量设置为命令行命令并(可能)造成巨大的破坏。一般来说,不要使用system()。通过 C 库实现几乎总是有更好的解决方案。

      【讨论】:

        猜你喜欢
        • 2022-06-20
        • 2013-09-08
        • 1970-01-01
        • 2020-11-03
        • 1970-01-01
        • 2011-07-08
        • 2014-10-09
        相关资源
        最近更新 更多