C 使用程序从中查找执行文件的名称

C 使用程序从中查找执行文件的名称,c,C,我正在寻找一种方法来查找运行它的可执行文件的名称。这意味着,如果我有一个名为program的文件,它运行的东西我想知道它的名字 使用_文件_不适合我,因为我需要的是可执行文件名,而不是包含代码的C文件名 我想知道是否有一个gcc宏可以帮助我,或内置的功能,我找不到 编辑: 此外,使用argv[0]也不合适,因为我不仅需要在main内部调用该函数 将argv[0]参数传递给可能需要该参数的所有函数也是不可接受的,因为它将在整个系统中使用,我需要使用它进行散列。C中main的标准定义是: argv[

我正在寻找一种方法来查找运行它的可执行文件的名称。这意味着,如果我有一个名为program的文件,它运行的东西我想知道它的名字

使用_文件_不适合我,因为我需要的是可执行文件名,而不是包含代码的C文件名

我想知道是否有一个gcc宏可以帮助我,或内置的功能,我找不到

编辑: 此外,使用argv[0]也不合适,因为我不仅需要在main内部调用该函数


将argv[0]参数传递给可能需要该参数的所有函数也是不可接受的,因为它将在整个系统中使用,我需要使用它进行散列。

C中main的标准定义是:

argv[0]包含已执行程序的名称

int main(int argc,char* argv[])
{
    printf("%s",argv[0]);
    return 0;
}
第一个参数argv[0]包含正在运行的程序的名称。

从main,将argv[0]传递到可能需要程序名称的任何位置

或者,如果许多函数需要它,并且您希望避免过多地传递它,请将其分配给全局变量

您要求使用宏作为解决方案,但它们在编译时进行了扩展。由于可执行文件的名称可以在编译后更改,因此无法在编译时确定所需的内容,因此宏是不存在问题的。

经常记住main中的argv[0]就足够了

如果情况并非如此-例如,如果您是共享库,或者如果您担心调用者使用伪造的argv[0]启动您,这是可能的,但并不常见,那么您可以在安装了/proc的POSIX兼容系统上,使用解析/proc/self/exe并获取运行进程的主二进制文件的路径:

#include <limits.h>
#include <unistd.h>

// Note that readlink does not null-terminate the result itself. This
// is important if the link target contains null bytes itself, I suppose,
// but it means that you have to take care that the null-terminator is
// placed yourself if you're going to use the file name as a string.
char buf[PATH_MAX] = { 0 };
readlink("/proc/self/exe", buf, PATH_MAX);

启动名称通过main的argv[0]给出,可以认为是常量

那么,为什么不在程序中使用对它的全局引用来提供它呢

progname.h

#ifndef PROGNAME_H
#define PROGNAME_H

extern char * progname;

#endif
main.c

#include "progname.h"

char * progname = NULL;

int main(int argc, char ** argv)
{
  progname = argv[0];

  ...

}
从任何类似的地方访问它

模块1.c

#include <stdio.h>
#include "progname.h"

void f(void)
{
  printf("progname='%s'\n", progname ?progname :"<not set>");
}

@天顶thnx。我只是将其添加为注释,指定它不符合我的需要。您需要它才能在Windows上工作,还是POSIX系统足够?我正在Linux上运行它,但您不能将argv[0]传递给需要它的代码的任何部分吗?或者只是将argv[0]设置为一个全局变量,或者如果传递太多?宏是在编译时展开的,因此,如果有人在编译后更改可执行文件的名称,宏是毫无疑问的。您好,谢谢,很抱歉,使用argv[0]不符合我的需要,当您回答.OP时,我正在用edit添加它。它提到了argv[0]。这是一个非常奇怪的要求。这是代码吗?安东,你可以定义全局指针,比如char*exeName;在main函数中,像exeName=argv[0];一样分配它;。因此,此全局字符串将可用于代码中的任何函数。您好,谢谢,很抱歉,使用argv[0]不符合我的需要,您回答时我只是用edit添加了它。@Anton.P复制argv[0]的内容并按您的意愿使用它?@Anton.P请用argv[0]将其标记为edit,否则来这里的人会认为那个酷家伙完全误解了question@iharob这是一种可能性,但我不想将名称作为参数传递给可能使用此功能的每个函数。不幸的是,这太多了。@Anton.P然后使用一个全局变量,但我会传递这个变量。这个程序相当大,包含几十个这样的模块,我正在添加的功能是一个小功能,我不想为了添加一个小功能而对所有模块进行更改。@Anton.P我能看到的唯一解决方案是添加两行来定义一个全局变量,并主要为其赋值argv[0]。两个小的行是不是修改太多了?我觉得你不需要对所有模块进行修改。
#include "progname.h"

char * progname = NULL;

int main(int argc, char ** argv)
{
  progname = argv[0];

  ...

}
#include <stdio.h>
#include "progname.h"

void f(void)
{
  printf("progname='%s'\n", progname ?progname :"<not set>");
}