如何获得程序运行的目录?
是否有一个平台不可知的和文件系统无关的方法来获得从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永远不会被认为是外部库,因为它为操作系统提供了基本的标准兼容接口。
在窗口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);
如果你想要一个没有图书馆的标准方法:不是。目录的整个概念不包括在标准中。
如果你同意对一个接近标准的lib的一些(可移植的)依赖性是可以的:使用Boost的文件系统库并且询问initial_path() 。
恕我直言,你可以得到尽可能接近,良好的业力(升压是一个完善的高品质的图书馆)
这是来自cplusplus论坛
在Windows上:
#include <string> #include <windows.h> std::string getexepath() { char result[ MAX_PATH ]; return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) ); }
在Linux上:
#include <string> #include <limits.h> #include <unistd.h> 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 <string> #include <limits.h> #define _PSTAT64 #include <sys/pstat.h> #include <sys/types.h> #include <unistd.h> 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 ); }
我知道现在在这个问题上答案已经很晚了,但是我发现没有一个答案像我自己的解决方案一样对我有用。 从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("\\"));
我认为这应该工作,但没有测试,所以评论将不胜感激,如果它的工作或修复,如果不是。
Filesystem TS 现在是一个标准 (由gcc 5.3+和clang 3.9+支持),所以你可以使用它的current_path()
函数:
std::string path = std::experimental::filesystem::current_path();
在gcc(5.3+)中包含文件系统,你需要使用:
#include <experimental/filesystem>
并用-lstdc++fs
标志链接你的代码。
如果您想使用Microsoft Visual Studio的Filesystem, 请阅读本文 。
不,没有标准的方法。 我相信C / C ++标准甚至不考虑目录(或其他文件系统组织)的存在。
在Windows上,当hModule参数设置为NULL时, GetModuleFileName()将返回当前进程的可执行文件的完整路径。 我无法帮助Linux。
此外,你应该澄清是否要当前目录或程序映像/可执行文件所在的目录。 就目前而言,你的问题在这一点上有点模棱两可。
也许连接当前的工作目录与argv [0]? 我不知道这是否会在Windows中工作,但它在Linux中的作品。
例如:
#include <stdio.h> #include <unistd.h> #include <string.h> 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
你不能为此使用argv [0],通常它包含可执行文件的完整路径,但不是一成不变的 – 在字段中可以用任意值创建进程。
另外请注意,当前目录和可执行目录是两个不同的东西,所以getcwd()也不会帮助你。
在Windows上使用GetModuleFileName(),在Linux上读取/ dev / proc / procID / ..文件。
对于Win32 GetCurrentDirectory应该做的伎俩。
只是迟来堆在这里,…
没有标准的解决方案,因为语言与底层文件系统是不可知的,所以正如其他人所说,基于目录的文件系统的概念已经超出了C / C ++语言的范围。
最重要的是,你不想要当前的工作目录,而是运行程序的目录,这个目录必须考虑到程序到达的位置 – 也就是说,它是通过一个fork来产生一个新的进程。正如解决方案已经证明的那样,要获取运行程序的目录,需要从操作系统的进程控制结构(这是该问题的唯一权威机构)获取该信息。 因此,按照定义,它是一个操作系统特定的解决方
在Windows上,最简单的方法是使用stdlib.h中的_get_pgmptr函数获取指向可执行文件绝对路径的字符串的指针,包括可执行文件的名称。
char* path; _get_pgmptr(&path); printf(path); // Example output: C:/Projects/Hello/World.exe
对于控制台上的Windows系统,您可以使用system( dir
)命令。 控制台为您提供有关目录等的信息。阅读cmd
的dir
命令。 但对于类Unix系统,我不知道…如果这个命令运行,请阅读bash命令。 ls
不显示目录…
例:
int main() { system("dir"); system("pause"); //this wait for Enter-key-press; return 0; }
在POSIX平台上,可以使用getcwd() 。
在Windows上,您可以使用_getcwd() ,因为getcwd()的使用已被弃用。
对于标准库,如果Boost对你来说足够标准,我会建议Boost :: filesystem,但是他们似乎已经从提议中删除了路径标准化。 您可能需要等到TR2完全可用于完全标准的解决方案。
#include <windows.h> using namespace std; // The directory path returned by native GetCurrentDirectory() no end backslash string getCurrentDirectoryOnWindows() { const unsigned long maxDir = 260; char currentDir[maxDir]; GetCurrentDirectory(maxDir, currentDir); return string(currentDir); }
相对路径,这是我做的。 我知道这个问题的年龄,我只是想提供一个更简单的答案,在大多数情况下工作:
假设你有这样一条路径:
"path/to/file/folder"
出于某种原因,在eclipse中制作的Linux生成的可执行文件正常工作。 但是,如果给定一个这样的路径,窗口会变得非常困惑!
如上所述,有几种方法可以将当前路径导入到可执行文件中,但是在大多数情况下,我发现最简单的方法是将其添加到路径的FRONT中:
"./path/to/file/folder"
只要添加“./”应该让你排序! :)然后,你可以开始从任何目录加载,只要它是可执行文件本身。
编辑:如果您尝试从code :: blocks启动可执行文件,这将无法正常工作,如果这是使用的开发环境,由于某些原因Code :: blocks不会加载正确的东西…:D
编辑2:我发现了一些新的东西,如果你在你的代码中指定一个像这样的静态路径(假设Example.data是你需要加载的):
"resources/Example.data"
如果你从实际的目录启动你的应用程序(或者在Windows中,你创建了一个快捷方式,并将工作目录设置为你的应用程序目录),那么它将以这种方式工作。 在调试与缺少资源/文件路径相关的问题时,请记住这一点。 (特别是在从IDE启动构建EXE时,设置了错误的工作目录的IDE)
Boost Filesystem的initial_path()
行为与POSIX的getcwd()
相似,也不是你自己想要的,但是将argv[0]
附加到它们中的任何一个都应该这样做。
你可能会注意到结果并不总是很漂亮 – 你可能会得到像/foo/bar/../../baz/a.out
或/foo/bar//baz/a.out
这样的东西,但我相信它始终会生成一个有效的路径来命名可执行文件(请注意,路径中的连续斜杠将折叠为一个)。
我以前用envp
( main()
的第三个参数写了一个解决方案,它在Linux上工作,但是在Windows上看起来不太可行,所以我基本上推荐了和其他人一样的解决方案,但是附加的解释是为什么即使结果不美观也是正确的。
正如Minok所说,ini C标准或C ++标准没有指定这样的功能。 这被认为是纯粹的操作系统特有的功能,例如在POSIX标准中指定。
Thorsten79给出了很好的建议,是Boost.Filesystem库。 但是,如果您不想在程序中使用二进制形式的链接时间依赖关系,则可能会很不方便。
我建议的一个很好的选择是收集100%只有标题的STLSoft C ++库 Matthew Wilson (关于C ++的必读书籍的作者)。 有便携的外观PlatformSTL可以访问系统特定的API:Windows的WinSTL和Unix的UnixSTL,所以它是可移植的解决方案。 所有系统特定的元素都是使用特征和策略来指定的,所以它是可扩展的框架。 当然有提供的文件系统库。
progname的linux bash命令将报告一个路径到程序。
即使你可以在你的程序中发出哪个命令,并将输出指向一个tmp文件,然后程序读取这个tmp文件,它也不会告诉你这个程序是否执行。 它只会告诉你具有该名称的程序在哪里。
所需要的是获取你的进程ID号,并解析出名称的路径
在我的程序中,我想知道该程序是从用户的bin目录还是从路径中的其他目录执行,或者从/ usr / bin中执行。 / usr / bin将包含受支持的版本。 我的感觉是,在Linux中有一个便携式的解决方案。
一个库解决方案(虽然我知道这不是要求)。 如果你碰巧使用Qt: QCoreApplication::applicationDirPath()