是否存在与平台无关且与文件系统无关的方法来获取使用C/C++运行程序的目录的完整路径?不要与当前的工作目录混淆.(请不要建议使用库,除非它们是clib或STL等标准库.)
(如果没有平台/文件系统无关的方法,也欢迎在Windows和Linux中使用特定文件系统的建议.)
这是获取执行应用程序的完整路径的代码:
视窗:
int bytes = GetModuleFileName(NULL, pBuf, len); if(bytes == 0) return -1; else return bytes;
Linux的:
char szTmp[32]; sprintf(szTmp, "/proc/%d/exe", getpid()); int bytes = MIN(readlink(szTmp, pBuf, len), len - 1); if(bytes >= 0) pBuf[bytes] = '\0'; return bytes;
如果在程序首次启动时获取当前目录,则可以有效地获取程序启动目录.将值存储在变量中,稍后在程序中引用它.这与保存当前可执行程序文件的目录不同.它不一定是同一个目录; 如果有人从命令提示符运行程序,则程序正在从命令提示符的当前工作目录运行,即使程序文件位于其他位置.
getcwd是一个POSIX功能,所有POSIX兼容平台都支持开箱即用.你不需要做任何特别的事情(除了在Unix上使用unistd.h和在windows上使用direct.h).
由于您正在创建一个C程序,它将链接到默认的c运行时库,该库由系统中的所有进程链接(避免特制的异常),默认情况下它将包含此函数.CRT从不被视为外部库,因为它为操作系统提供了基本的标准兼容接口.
在Windows上,getcwd函数已被弃用,转而使用_getcwd.我想你可以用这种方式使用它.
#include/* defines FILENAME_MAX */ #ifdef WINDOWS #include #define GetCurrentDir _getcwd #else #include #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);
这是来自cplusplus论坛
在Windows上:
#include#include std::string getexepath() { char result[ MAX_PATH ]; return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) ); }
在Linux上:
#include#include #include std::string getexepath() { char result[ PATH_MAX ]; ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX ); return std::string( result, (count > 0) ? count : 0 ); }
在HP-UX上:
#include#include #define _PSTAT64 #include #include #include std::string getexepath() { char result[ PATH_MAX ]; struct pst_status ps; if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0) return std::string(); if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0) return std::string(); return std::string( result ); }
如果你想要一个没有库的标准方法:不.目录的整个概念不包含在标准中.
如果您同意对近标准库的某些(可移植)依赖是可以的:使用Boost的文件系统库并请求initial_path().
恕我直言,尽可能接近,有良好的业力(Boost是一套完善的高质量图书馆)
Filesystem TS 现在是一个标准(并受gcc 5.3+和clang 3.9+支持),所以你可以使用current_path()
它的功能:
std::string path = std::experimental::filesystem::current_path();
在gcc(5.3+)中包含Filesystem,你需要使用:
#include
并将您的代码与-lstdc++fs
旗帜相关联.
如果要将文件系统与Microsoft Visual Studio一起使用,请阅读此内容.
我知道现在很晚才回答这个问题,但我发现没有一个答案对我来说和我自己的解决方案一样有用.从CWD到bin文件夹获取路径的一种非常简单的方法是这样的:
int main(int argc, char* argv[]) { std::string argv_str(argv[0]); std::string base = argv_str.substr(0, argv_str.find_last_of("/")); }
您现在可以将其用作相对路径的基础.所以例如我有这个目录结构:
main ----> test ----> src ----> bin
我想编译我的源代码到bin并写一个日志来测试我可以把这行添加到我的代码中.
std::string pathToWrite = base + "/../test/test.log";
我已经在Linux上使用完整路径,别名等尝试了这种方法,它工作得很好.
注意:
如果你在Windows上,你应该使用'\'作为文件分隔符而不是'/'.你也必须逃避这个例子:
std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));
我认为这应该有效但尚未经过测试,因此如果有效,则表示赞赏,如果没有,则表示感谢.
不,没有标准的方法.我相信C/C++标准甚至不考虑目录(或其他文件系统组织)的存在.
在Windows上,当hModule参数设置为NULL时,GetModuleFileName()将返回当前进程的可执行文件的完整路径.我无法帮助Linux.
此外,您应该澄清是否需要当前目录或程序映像/可执行文件所在的目录.就目前而言,你的问题在这一点上有点含糊不清.
也许用argv [0]连接当前的工作目录?我不确定它是否适用于Windows,但它适用于Linux.
例如:
#include#include #include int main(int argc, char **argv) { char the_path[256]; getcwd(the_path, 255); strcat(the_path, "/"); strcat(the_path, argv[0]); printf("%s\n", the_path); return 0; }
运行时,输出:
jeremy @ jeremy-desktop:〜/ Desktop $ ./test
/home/jeremy/Desktop/./test
对于Win32,GetCurrentDirectory应该可以解决问题.
在Windows上,最简单的方法是使用_get_pgmptr
函数stdlib.h
来获取指向字符串的指针,该字符串表示可执行文件的绝对路径,包括可执行文件名称.
char* path; _get_pgmptr(&path); printf(path); // Example output: C:/Projects/Hello/World.exe
您不能将argv [0]用于此目的,通常它确实包含可执行文件的完整路径,但不是必须的 - 可以在字段中使用任意值创建进程.
还要注意,当前目录和带有可执行文件的目录是两个不同的东西,所以getcwd()也无法帮助你.
在Windows上使用GetModuleFileName(),在Linux上读取/ dev/proc/procID/..文件.