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

4
如果我有这个:
int main(int argc, char *argv[])

在程序中,有时可以使用argv[1]来获取参数。
什么时候我们会使用argv[1]而不是argv[0]呢?只有当我们想要读取命令行中的第二个参数时才使用吗?
7个回答

12

按照惯例argv[0] 表示当前程序的名称(或路径),argv[1]argv[argc - 1] 则是用户提供的命令行参数

然而,这并不一定是真实情况-- 程序可以使用特定于操作系统的功能来绕过此要求,这种情况经常发生,您应该意识到这一点。(不过,即使您意识到了这一点,我不确定您能做什么...)

例如:

gcc -O3 -o temp.o "My file.c"

应该会产生以下参数:

argc: 5
argv: ["gcc", "-O3", "-o", "temp.o", "My file.c"]

因此,说argv[0]将引用gcc,而不是-O3


好的,argv [0] 不必是可执行文件的真实路径,但 argv [1]..argv [argc-1] 必须是命令行参数 :-). - Tony Delroy
6
如果argc的值大于零,argv [0]指向的字符串表示程序名称;如果主机环境不提供程序名称,则argv[0][0]应该是空字符。 如果argc的值大于1,则argv [1]argv [argc-1]指向的字符串表示程序参数。 - Chris Lutz
1
+1,按照惯例(也就是因为标准这样规定)argv[argc]的值应为'0'§3.6.1/2 [...] argv [argc] 的值必须为0。 - David Rodríguez - dribeas
3
@Chris:当然,UNIX/Linux 也是一样的:所有 exec 函数族都允许执行进程为其子进程指定 argv 值 - 按照惯例,这个值是子进程的可执行文件名,但是有一个众所周知的几十年历史的黑客技巧,可以隐藏你运行的程序(例如 irc),看起来好像在运行 vim:只需编写一个小程序,在其中强制将前者作为后者的 argv[0] 参数调用即可。这样一来,简单的 ps 等命令就会显示你正在工作。 - Tony Delroy
2
@Tony - 如果有人使用exec来欺骗程序,让它认为自己的名字是其他的东西,那么我们应该期望这个程序会认为它的名字是我们告诉它的任何东西,不是吗?因此,一个程序应该相信argv[0]就是它的名字,如果我们欺骗了我们的子程序,我们应该感到适当的羞耻。 ;) - Chris Lutz
显示剩余6条评论

6

argv 是一个指针数组,该数组中的每个指针都存储来自命令行的一个参数。因此,argv[0] 是第一个参数(即可执行文件/程序本身),argv[1] 是第二个参数,以此类推!

参数的总数由 argc 决定。


1
为什么是-1:这完全正确。argv [1]是由shell解释的命令行上的第二个参数。它是应用程序应该解释的第一个参数。 - Martin York
@Nawaz - 有人可能是在看之前就跳了。给你点赞,放心吧,这个回答让你获得了28个声望值的净增长。 :) - Chris Lutz
@Nawaz:one vs the或a只是一个次要但值得改进的地方(我本来不想提的)。除此之外,我心中仍有一点疑虑(即使接受Linux手册的用法),那就是你所说的“来自命令行的参数”和参数列表的区别。你可以考虑用"argument list"替换"command line",或者添加引号来支持参数列表包括程序名称的想法,但这取决于你... - Tony Delroy
@Tony:只要你明白 argv[0] 是可执行文件本身,那术语的问题又有什么关系呢?你讨论的只是术语,而不是概念或程序如何工作的问题! - Nawaz
@Nawaz:这很重要,因为我们试图明确地传达程序的工作方式,如果我们没有普遍理解的术语,那么我们对事物运作方式的陈述可能会被读者理解为意味着不同于预期的概念和行为。 (如果您减少对术语的依赖,并展示个别值如何映射到argv[]内容 - 正如Oscar和Mehrdad在他们的答案中所做的那样 - 那么就会减少混淆的空间。) - Tony Delroy
显示剩余7条评论

2

argv[0] 是程序的执行路径,argv[1] 是程序的第一个参数


2

假设您的C++可执行文件是:

/home/user/program(在Windows中为C:\program.exe

如果您执行:

./home/user/program 1 2(在Windows中为C:\program.exe 1 2

argv[0] = /home/user/programC:\program.exe
argv[1] = 1
argv[2] = 2

这是因为:

  • argv [0]是可执行文件的路径
  • argv [1]是第一个参数

编辑:

我现在看到argv [0]不一定是可执行文件的路径。
请阅读以下SO问题:Is args [0] guaranteed to be the path of execution?


1
请注意,如果 argc == 1,则 argv[1] 不存在。argc 不是参数的数量,而是 argv 的大小(比参数数量多 1)。 - Chris Lutz
1
@Cris Lutz:相反,如果argc == 1,则argv [1] == 0。§3.6.1/2明确指出argv [argc] == 0 - David Rodríguez - dribeas
@David - 在看了Mehrdad的回答之前,我其实并不知道那个。很高兴知道我不能逃避这个问题。 - Chris Lutz

0

是的,基本上就是这样,argv [1] 是第二个命令行参数。第一个命令行参数是程序本身的名称。

或者,为了避免这个答案最初存在的语义混乱和其他人的评论,可以将 argv [0] 称为“零”参数,这样 argv [1] 就成为用户提供的值中的“第一”个。

无论如何,这来自于 exec() 函数族,例如具有用法的 execl

 int execl(const char *path, const char *arg0, ... /*, (char *)0 */);

在(Unix)shell中,当你键入命令时,如果必要的话,shell首先会解析命令名称(使用$PATH),以查找真正的绝对路径。绝对或相对路径作为path提供,并且最初键入的命令作为arg0提供,最终成为程序中的argv [0]

其余的命令行参数最终变成argv[1]等。


3
哎?我不确定你在这里所说的"argument" 的定义是什么,但据我所知它应该是指第一个参数,而不是第二个... - user541686

0

简短的回答是,数组包含传递到程序中的所有选项。


0

由于argv [0]是程序本身的文件路径。 额外的命令行参数在进一步的索引中,argv [1],argv [2]等。 您可以在此处阅读更多信息: {{link1:http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html}}


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