You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++跨平台实现文件保存至EXE所在目录的技术问询

CLI应用跨平台固定路径存储文件解决方案

核心问题:为什么argv[0]不好用

  • 当通过系统PATH环境变量调用程序时,argv[0]只会返回程序文件名(比如CLI_App.exe),拿不到完整路径
  • 部分调用场景下还会返回异常值(比如你碰到的true),完全没法用来定位程序所在目录

跨平台实现步骤

1. 用系统API获取程序完整路径

不同平台需要调用各自的系统接口来获取可执行文件的绝对路径:

Windows平台

调用GetModuleFileNameW接口:

#include <windows.h>
#include <string>

std::wstring get_exe_dir() {
    wchar_t path[MAX_PATH];
    GetModuleFileNameW(NULL, path, MAX_PATH);
    // 截取目录部分(去掉文件名)
    std::wstring full_path(path);
    size_t last_slash = full_path.find_last_of(L"\\/");
    return full_path.substr(0, last_slash + 1);
}

Linux/macOS平台

Linux用readlink读取/proc/self/exe,macOS用_NSGetExecutablePath做 fallback:

#include <string>
#include <unistd.h>
#include <limits.h>
#include <mach-o/dyld.h> // macOS专属头文件

std::string get_exe_dir() {
    char path[PATH_MAX];
    // 先尝试Linux方式
    ssize_t len = readlink("/proc/self/exe", path, PATH_MAX - 1);
    if (len != -1) {
        path[len] = '\0';
        std::string full_path(path);
        size_t last_slash = full_path.find_last_of("/");
        return full_path.substr(0, last_slash + 1);
    }
    // 失败则用macOS方式
    uint32_t mac_len = PATH_MAX;
    if (_NSGetExecutablePath(path, &mac_len) == 0) {
        std::string full_path(path);
        size_t last_slash = full_path.find_last_of("/");
        return full_path.substr(0, last_slash + 1);
    }
    return "";
}

2. 拼接目标文件路径

拿到程序所在目录后,直接拼接文件名即可:

// Windows示例
std::wstring exe_dir = get_exe_dir();
std::wstring target_file = exe_dir + L"example.txt";

// Linux/macOS示例
std::string exe_dir = get_exe_dir();
std::string target_file = exe_dir + "example.txt";

这样不管你在哪个目录下调用程序,文件都会被精准保存到CLI_App.exe所在的目录,不会出现误在当前目录新建同名文件的情况。

3. 跨平台统一封装(可选)

用预编译指令把两个平台的代码封装成一个统一函数,方便跨平台编译:

#include <string>

#ifdef _WIN32
#include <windows.h>
std::wstring get_exe_directory() {
    wchar_t path[MAX_PATH];
    GetModuleFileNameW(NULL, path, MAX_PATH);
    std::wstring full_path(path);
    size_t last_sep = full_path.find_last_of(L"\\/");
    return full_path.substr(0, last_sep + 1);
}
#else
#include <unistd.h>
#include <limits.h>
#include <mach-o/dyld.h>
std::string get_exe_directory() {
    char path[PATH_MAX];
    ssize_t len = readlink("/proc/self/exe", path, PATH_MAX - 1);
    if (len != -1) {
        path[len] = '\0';
        std::string full_path(path);
        size_t last_sep = full_path.find_last_of("/");
        return full_path.substr(0, last_sep + 1);
    }
    uint32_t mac_len = PATH_MAX;
    if (_NSGetExecutablePath(path, &mac_len) == 0) {
        std::string full_path(path);
        size_t last_sep = full_path.find_last_of("/");
        return full_path.substr(0, last_sep + 1);
    }
    return "";
}
#endif

验证方法

  • 在不同目录下调用程序,比如C:\Users\Me> CLI_App.exe或/home/user> CLI_App
  • 检查example.txt是否出现在程序所在的目录,而非你调用时的当前目录

内容的提问来源于stack exchange,提问作者1cubealot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:22:40