C++ 如果无法访问argv[0],如何获取程序名?

C++ 如果无法访问argv[0],如何获取程序名?,c++,c,linux,command-line-arguments,C++,C,Linux,Command Line Arguments,我知道程序名作为第一个参数传递,下一个简单示例将把它打印到标准输出: #include <iostream> int main ( int argc, char *argv[] ) { std::cout<<argv[0]<<std::endl; } #包括 int main(int argc,char*argv[]) { 标准::cout这不是保证 通常,argv[0]保存可执行文件名,但可以使用execve调用可执行文件并将其设置为其他名称 一句话:

我知道程序名作为第一个参数传递,下一个简单示例将把它打印到标准输出:

#include <iostream>
int main ( int argc, char *argv[] )
{
  std::cout<<argv[0]<<std::endl;
}
#包括
int main(int argc,char*argv[])
{

标准::cout这不是保证

通常,
argv[0]
保存可执行文件名,但可以使用
execve
调用可执行文件并将其设置为其他名称

一句话:不要依赖于此。

不,这完全取决于父程序在其中放置了什么

exec
函数系列允许可执行文件名与传入的参数完全不同,ISO C标准支持这一点

如果argc的值大于零,则argv[0]指向的字符串表示程序名;如果主机环境无法提供程序名,则argv[0][0]应为空字符

因此,如果名称可用,则只有程序名称。前面的部分说明:

如果argc的值大于零,则数组成员argv[0]到argv[argc-1]应包含指向字符串的指针,这些字符串在程序启动之前由主机环境给定实现定义的值

(我的斜体)

因此,即使它们的值不是由标准规定的,也完全取决于实现。这意味着,如果主机环境不提供程序名,则程序名可以为空,如果主机环境提供程序名,则程序名可以为空

然而,定义的实现在ISO标准中有一个特定的含义——实现必须记录它是如何工作的。因此,即使是UNIX,它可以通过调用的
exec
系列将它喜欢的任何东西放入
argv[0]
,也必须(并且确实)记录它

类似地(感谢Chubsdad),C++03声明:

“如果argc为非零,则应在argv[0]到argv[argc-1]中提供这些参数,作为指向以空结尾的多字节字符串(NTMBS)(17.3.2.1.3.2)的初始字符的指针,并且argv[0]应是指向NTMBS的初始字符的指针,该NTMBS表示用于调用程序的名称或”“。”

因此,即使在那里,argv[0]也可能不包含任何内容,即使它包含任何内容,“表示名称”也是一个非常模糊的要求。它不必是可执行文件的完整路径名,甚至不必包含用于调用它的命令


在Linux下执行此操作的另一种方法是使用
proc
文件系统。我认为
/proc/self/exe
是指向可执行文件的链接


Wikipedia为文件系统提供了一个条目,其中包含很多好东西。

您可以使用getpid()确定进程的pid,然后检查/proc/[pid number]的内容使用标准I/O工具。

不,没有这样的功能。Linux将程序名存储在
\uu progname
中,但这不是一个公共接口。如果您想将其用于警告/错误消息,请使用
err(3)
功能

如果需要运行程序的完整路径,请在
/proc/self/exe
上调用
readlink

char *program_path()
{
    char *path = malloc(PATH_MAX);
    if (path != NULL) {
        if (readlink("/proc/self/exe", path, PATH_MAX) == -1) {
            free(path);
            path = NULL;
        }
    }
    return path;
}

(我相信
\uuu progname
被设置为
argv[0]
的基本名称。请查看glibc源代码以确保。)

如果使用GLib,您可以使用该函数。在Win32上,它调用任何其他函数时,它似乎都返回NULL。

glibc特定的解决方案:

#include <errno.h>
...
fprintf(stderr, "Program name is %s\n", program_invocation_name);
#包括
...
fprintf(stderr,“程序名为%s\n”,程序调用名);
人工调用\u name

program\u invocation\u name
包含用于调用调用程序的名称。这与
main()
中的
argv[0]
的值相同,不同之处在于
program\u invocation\u name
的范围是全局的

program\u invocation\u short\u name
包含用于调用调用程序的name的basename组件。也就是说,它的值与
program\u invocation\u name
的值相同,删除了包括最后斜杠(/)在内的所有文本


你是什么意思?你刚才说你知道“程序名”是作为第一个参数传递的……那么你还需要什么呢?@mt_serg,@Kelsey Rider如果你仔细阅读这个问题,问题很简单,它说“argv[0]用于查找程序名,但是是否还有其他函数来获取程序名?“。无意冒犯:)@Searock没有冒犯,只是误解。peace:-)从库的角度来看,问题的可能重复很有意义。此外,至少在Windows上,
argv[0]
可能包含完整路径以及扩展名为w\或w\o的可执行文件名。argv[0]始终是我认为的程序名。@Chubsdad:ereOn刚刚指出,这可能不是真的。因此,不,它并不总是程序名。@Chubsdad:If you know,写出自己的答案。如果你只思考,那就去查找或等待知道答案的人回答。目前你错了(在跟随Buh的Linux上,这个参数是用户所面临的:BASH -C’Exc-一个在ARGV(0)中的漂亮程序名。/可执行的C++标准(03)状态:“如果ARGC是非零,这些参数应该通过ARGV [ARGC-1 ]在ARGV(0)中提供。作为指向以null结尾的多字节字符串(NTMBS)(17.3.2.1.3.2)初始字符的指针,argv[0]应是指向NTMBS初始字符的指针,该字符表示用于调用程序的名称或““那么,C++和C++的行为可能不同吗?”我不这么认为,@ Chubsdad:这与C标准似乎没有什么不同。<代码> ARGV(0)< /C>可以表示程序名或空。注意也就是黄鼠狼单词“代表姓名”。-这绝不是可执行文件的完整路径,甚至不是部分匹配。也许我很愤世嫉俗,但是字符串