如何获取并存储正在运行的C程序名称,处理argv[0]的./前缀问题
C语言获取运行程序名称的正确实现方案
原代码报错原因
- 第一段遍历代码仅去掉了首字符
.,没有处理后续的/,且遍历结束后未手动给exec_path添加字符串结束符\0,导致后续字符串操作读取到内存垃圾值,触发运行错误 - 后续的
memcpy实现存在兼容性隐患:如果argv[0]不是以./开头(比如用绝对路径、上层相对路径../启动程序),直接偏移2位会导致取值错误;如果executableName是指针类型,sizeof(executableName)取到的是指针长度而非字符串实际长度,容易出现内存溢出、字符串截断问题
优雅实现方案(无需第三方库,用标准库即可)
可以直接使用libgen.h头文件中自带的basename()函数,该函数会自动剥离传入路径的所有前缀(包括相对路径./、../、绝对路径等),直接返回纯程序名,兼容所有启动场景:
#include <stdio.h> #include <string.h> #include <libgen.h> #include <limits.h> int main(int argc, char* argv[]) { char exec_path[PATH_MAX]; // 自动提取纯程序名,忽略所有路径前缀 char* proc_name = basename(argv[0]); // 拼接自定义路径,这里的name替换为你自己的路径变量即可 snprintf(exec_path, PATH_MAX, "%s/%s", name, proc_name); // 如果你确实只需要去掉开头的./前缀,保留其他路径结构,可以用以下安全写法 /* const char* executableName = argv[0]; const char* name_ptr = executableName; // 先判断前缀匹配再偏移,避免越界 if (strlen(executableName) >= 2 && executableName[0] == '.' && executableName[1] == '/') { name_ptr = executableName + 2; } snprintf(exec_path, PATH_MAX, "%s/%s", name, name_ptr); */ return 0; }
注意事项
basename()函数会修改传入的原字符串,如果需要保留原argv[0]的内容,可以先拷贝一份再传入basename()- 拼接路径时要确保
name变量本身没有末尾的/,否则拼接后会出现双斜杠的情况,也可以提前做判断处理
内容的提问来源于stack exchange,提问作者Shenladen
相关产品推荐
相关产品推荐

