__progname
而不是argv [0]
。 这样做有什么优势吗? __progname
和argv [0]
之间有什么区别? 它是否可移植?__progname
不是标准的,因此不具备可移植性,请使用 argv[0]
。我猜想 __progname
可以查找一个字符串资源来获取名称,这并不依赖于您运行它的文件名。但是,argv[0]
将为您提供实际运行的名称,我认为这更有用。
__progname
可以让您在保留程序名称的同时更改argv[]
数组的内容。一些常见的工具,如getopt()
在处理参数时会修改argv[]
。argv[0]
复制到自己的progname
缓冲区中。此外,还有一个GNU扩展,可以在不手动保存程序调用名称的情况下从main()之外访问它。然而,手动保存可能更好,这样就可以使其具有可移植性,而不是依赖于GNU扩展。尽管如此,在此提供一段可用文档的摘录。
来自在线GNU C库手册(今天访问):
“许多不从终端读取输入的程序都设计为在任何系统调用失败时退出。按照惯例,这样的程序的错误消息应该以程序的名称开头,不包括目录。您可以在变量program_invocation_short_name
中找到该名称;完整的文件名存储在变量program_invocation_name
中。
变量:char * program_invocation_name
此变量的值是用于调用当前进程中运行的程序的名称。它与argv[0]
相同。请注意,这不一定是有用的文件名;通常它不包含目录名称。
变量:char * program_invocation_short_name
此变量的值是用于调用当前进程中运行的程序的名称,其中删除了目录名称。(也就是说,它与program_invocation_name
相同,减去最后一个斜杠之前的所有内容(如果有的话)。
库初始化代码在调用main之前设置这两个变量。
可移植性注意事项:这两个变量是GNU扩展。如果您希望您的程序能够与非GNU库一起使用,则必须在main中保存argv[0]
的值,然后自己剥离目录名称。我们添加了这些扩展,以便编写不需要来自main的显式协作的自包含错误报告子例程成为可能。”
这是一种BSD风格,绝对不可移植。
__progname就是argv[0],其他回复中的示例显示了使用它的弱点。虽然也不具备可移植性,但我在Linux和Android上使用/proc/self/exe上的readlink,并读取/proc/self/exefile(QNX)的内容。