std::filesystem::current_path() 是 C++17 起获取当前工作目录(CWD)的唯一可移植、线程安全方式,返回 std::filesystem::path 对象,需捕获 filesystem_error 异常,且不表示可执行文件路径。

用 std::filesystem::current_path() 获取当前工作目录
这是 C++17 标准提供的最直接、跨平台的方式。它返回的是当前工作目录(Current Working Directory, CWD),不是可执行文件所在路径,这点常被混淆。
常见错误是以为它能拿到程序安装路径或 main() 所在源码目录 —— 它不能。CWD 是进程启动时继承的,比如你在终端里 cd 到 /tmp 再运行程序,current_path() 就返回 /tmp。
实操建议:
- 确保编译器支持 C++17(如 GCC 8+、Clang 7+、MSVC 2017 Update 5+),并开启
-std=c++17 - 包含头文件:
#include <filesystem>,部分旧版 GCC 还需链接-lstdc++fs - 捕获异常:调用可能抛出
std::filesystem::filesystem_error,比如权限不足时
try {
auto p = std::filesystem::current_path();
std::cout << "CWD: " << p.string() << "
";
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << "Failed to get current path: " << e.what() << "
";
}
Windows 下用 GetModuleFileNameA() 拿可执行文件路径
如果目标是“程序自己在哪”,而不是“当前在哪个目录下”,Windows 原生 API 更可靠。C++ 标准库不提供获取可执行路径的接口,current_path() 也不管这个事。
立即学习“C++免费学习笔记(深入)”;
注意:GetModuleFileNameA() 返回的是完整路径(含文件名),需要手动截掉最后一段才能得到目录。
实操建议:
- 只在 Windows 平台可用,需
#include <windows.h> - 传
NULL作为第一个参数表示当前模块(即 .exe) - 缓冲区大小必须足够(通常给
MAX_PATH即 260 字节) - 记得用
PathRemoveFileSpecA()(#include <shlwapi.h>)或手动找最后一个'\'
HMODULE hMod = GetModuleHandleA(NULL); char path[MAX_PATH]; GetModuleFileNameA(hMod, path, MAX_PATH); PathRemoveFileSpecA(path); // path 现在是目录部分
Linux/macOS 下用 /proc/self/exe 或 _NSGetExecutablePath()
Linux 通过符号链接 /proc/self/exe 指向当前可执行文件;macOS 则用 _NSGetExecutablePath()(来自 <mach-o/dyld.h>)。两者都比依赖 CWD 更接近“程序在哪”这个真实需求。
容易踩的坑:
- Linux 上
readlink("/proc/self/exe", buf, size)返回的是实际路径,但若程序被硬链接或 symlink 启动,可能返回原始路径而非调用路径 - macOS 的
_NSGetExecutablePath()返回的路径含.app/Contents/MacOS/xxx结构,且缓冲区大小需先用0调用一次获取所需长度 - 这两个方法都不属于 C++ 标准,不可跨平台混用
示例(Linux):
char exe_path[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path)-1);
if (len != -1) {
exe_path[len] = ' ';
// 截断文件名:strrchr(exe_path, '/') + 1
}
为什么不用 getcwd()?
getcwd() 是 C 标准库函数,在 C++ 里仍可用(#include <unistd.h> 或 <direct.h>),但它和 std::filesystem::current_path() 本质一样 —— 都读当前工作目录,不是程序路径。
真正的问题在于语义混淆:用户搜“当前路径”,实际想要的可能是“我在哪启动的”(CWD)、“我的程序在哪”(exe path)、还是“我的配置文件该放哪”(install dir)。这三者完全不同。
关键提醒:没有银弹。选哪个取决于你到底要什么。如果写跨平台工具,建议封装一层判断逻辑,优先尝试 current_path()(CWD),再按平台 fallback 到各自可执行路径方案;同时文档里明确说明“本工具基于当前工作目录运行”,避免用户误以为它会自动找到资源子目录。


















