是否有一种平台不可知和文件系统不可知的方法来获取程序运行的目录的完整路径?不要与当前工作目录混淆。(请不要推荐库,除非它们是像clib或STL这样的标准库。)
(如果没有平台/文件系统不可知的方法,也欢迎在Windows和Linux中针对特定文件系统工作的建议。)
是否有一种平台不可知和文件系统不可知的方法来获取程序运行的目录的完整路径?不要与当前工作目录混淆。(请不要推荐库,除非它们是像clib或STL这样的标准库。)
(如果没有平台/文件系统不可知的方法,也欢迎在Windows和Linux中针对特定文件系统工作的建议。)
当前回答
在Windows上,最简单的方法是使用stdlib.h中的_get_pgmptr函数来获取一个指向字符串的指针,该字符串表示可执行文件的绝对路径,包括可执行文件的名称。
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
其他回答
下面的操作在macOS 10.15.7上运行得很好
brew install boost
main.cpp
#include <iostream>
#include <boost/filesystem.hpp>
int main(int argc, char* argv[]){
boost::filesystem::path p{argv[0]};
p = absolute(p).parent_path();
std::cout << p << std::endl;
return 0;
}
编译
g++ -Wall -std=c++11 -l boost_filesystem main.cpp
只是我的两美分,但下面的代码在c++ 17中不能移植吗?
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char* argv[])
{
std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
}
至少在Linux上对我有用。
根据前面的想法,我现在有:
std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");
与实现:
fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
{
static auto exe_parent_path = fs::path(exe_path).parent_path();
return exe_parent_path / filename;
}
main()中的初始化技巧:
(void) prepend_exe_path("", argv[0]);
感谢@Sam Redway的argv[0]想法。当然,我知道当OP提出这个问题时,c++ 17还没有出现很多年。
If you fetch the current directory when your program first starts, then you effectively have the directory your program was started from. Store the value in a variable and refer to it later in your program. This is distinct from the directory that holds the current executable program file. It isn't necessarily the same directory; if someone runs the program from a command prompt, then the program is being run from the command prompt's current working directory even though the program file lives elsewhere.
getcwd是一个POSIX函数,所有POSIX兼容平台都支持它。你不需要做任何特殊的事情(除了在Unix上包含正确的头文件unistd.h和在windows上包含direct.h)。
由于您正在创建一个C程序,它将链接到默认的C运行时库,该库由系统中的所有进程链接(避免特别设计的异常),默认情况下它将包含这个函数。CRT从来不被认为是一个外部库,因为它为操作系统提供了基本的标准兼容接口。
在windows上,getcwd函数已弃用,而支持_getcwd。我觉得你可以这样用。
#include <stdio.h> /* defines FILENAME_MAX */
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
return errno;
}
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */
printf ("The current working directory is %s", cCurrentPath);
你不能为此目的使用argv[0],通常它包含可执行文件的完整路径,但也不是必须的——进程可以在字段中使用任意值创建。
还要注意,当前目录和可执行文件所在的目录是两个不同的东西,所以getcwd()也帮不了你。
Windows上使用GetModuleFileName(), Linux上读取/dev/proc/procID/..文件。
当前.exe的路径
#include <Windows.h>
std::wstring getexepathW()
{
wchar_t result[MAX_PATH];
return std::wstring(result, GetModuleFileNameW(NULL, result, MAX_PATH));
}
std::wcout << getexepathW() << std::endl;
// -------- OR --------
std::string getexepathA()
{
char result[MAX_PATH];
return std::string(result, GetModuleFileNameA(NULL, result, MAX_PATH));
}
std::cout << getexepathA() << std::endl;