使用文件流时如何让程序不受用户当前工作目录(pwd)影响正常运行
问题根源
你遇到的问题本质是相对路径的基准是进程的当前工作目录(即执行命令时的pwd路径),而非可执行文件本身的存放目录,所以换目录执行就会找不到同目录下的input文件。
可行解决方案
方案1:自动获取可执行文件所在目录(最通用)
运行时先拿到程序自身的存放路径,剔除可执行文件名后得到所在目录,再和目标文件名拼接成绝对路径打开,完全不受工作目录影响,即使程序整体迁移目录也能正常运行。
跨平台示例代码:
#include <iostream> #include <fstream> #include <string> #ifdef _WIN32 #include <windows.h> #elif __linux__ #include <unistd.h> #include <limits.h> #elif __APPLE__ #include <mach-o/dyld.h> #include <limits.h> #endif // 获取可执行文件所在目录的路径 std::string get_executable_dir() { char path[PATH_MAX]; #ifdef _WIN32 GetModuleFileNameA(NULL, path, PATH_MAX); std::string full_path(path); size_t pos = full_path.find_last_of("\\/"); return full_path.substr(0, pos + 1); #elif __linux__ ssize_t len = readlink("/proc/self/exe", path, sizeof(path)-1); if (len != -1) { path[len] = '\0'; std::string full_path(path); size_t pos = full_path.find_last_of('/'); return full_path.substr(0, pos + 1); } return ""; #elif __APPLE__ uint32_t size = sizeof(path); if (_NSGetExecutablePath(path, &size) == 0) { std::string full_path(path); size_t pos = full_path.find_last_of('/'); return full_path.substr(0, pos + 1); } return ""; #endif } int main () { std::string input_path = get_executable_dir() + "input"; std::ifstream stream(input_path.c_str()); if (!stream.is_open()) { std::cout << "No file detected" << std::endl; return 1; } // 正常读取文件逻辑 stream.close(); return 0; }
方案2:编译期硬编码路径
适合程序固定放在某个路径下的场景,编译时把资源目录通过宏定义传进去即可:
编译命令示例(Linux):
g++ main.cpp -D RESOURCE_DIR="\"/home/xxx/my_project/\""
代码里直接用宏拼接路径:
std::ifstream stream(RESOURCE_DIR "input");
缺点是程序移动位置后需要重新编译才能正常使用。
方案3:通过启动参数/封装脚本传入路径
执行程序时把input文件的路径作为参数传入即可,也可以写个shell/bat脚本封装执行逻辑,自动切换到程序所在目录再执行:
shell脚本示例(和可执行文件、input放在同目录):
#!/bin/bash cd "$(dirname "$0")" || exit ./你的可执行文件名
用户直接执行脚本即可,不需要关心当前工作目录。
内容的提问来源于stack exchange,提问作者Elliott
相关产品推荐
相关产品推荐

