C++ 如何获取运行程序的目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/143174/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get the directory that a program is running from?
提问by Ashwin Nanjappa
Is there a platform-agnostic and filesystem-agnostic method to obtain the full path of the directory from where a program is running using C/C++? Not to be confused with the current working directory. (Please don't suggest libraries unless they're standard ones like clib or STL.)
是否有一种平台无关和文件系统无关的方法来获取使用 C/C++ 运行程序的目录的完整路径?不要与当前工作目录混淆。(请不要推荐库,除非它们是像 clib 或 STL 这样的标准库。)
(If there's no platform/filesystem-agnostic method, suggestions that work in Windows and Linux for specific filesystems are welcome too.)
(如果没有与平台/文件系统无关的方法,也欢迎提供在 Windows 和 Linux 中适用于特定文件系统的建议。)
采纳答案by Ashwin Nanjappa
Here's code to get the full path to the executing app:
这是获取正在执行的应用程序的完整路径的代码:
Windows:
视窗:
int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;
Linux:
Linux:
int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '#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] = '#include <string>
#include <windows.h>
std::string getexepath()
{
char result[ MAX_PATH ];
return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}
'; /* not really required */
printf ("The current working directory is %s", cCurrentPath);
';
return bytes;
回答by computinglife
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 fromthe command prompt's current working directory even though the program file lives elsewhere.
如果您在程序第一次启动时获取当前目录,那么您实际上拥有程序启动的目录。将值存储在变量中,稍后在程序中引用它。这与保存当前可执行程序文件的目录不同。它不一定是同一个目录;如果有人从命令提示符运行该程序,那么即使该程序文件位于其他位置,该程序也会从命令提示符的当前工作目录运行。
getcwd is a POSIX function and supported out of the box by all POSIX compliant platforms. You would not have to do anything special (apart from incliding the right headers unistd.h on Unix and direct.h on windows).
getcwd 是一个 POSIX 函数,所有 POSIX 兼容平台都支持开箱即用。您不必做任何特别的事情(除了在 Unix 上添加正确的标题 unistd.h 和在 Windows 上添加 direct.h 之外)。
Since you are creating a C program it will link with the default c run time library which is linked to by ALL processes in the system (specially crafted exceptions avoided) and it will include this function by default. The CRT is never considered an external library because that provides the basic standard compliant interface to the OS.
由于您正在创建一个 C 程序,它将与默认的 c 运行时库链接,该库由系统中的所有进程链接(避免特制异常),并且默认情况下它将包含此函数。CRT 从未被视为外部库,因为它为操作系统提供了符合基本标准的接口。
On windows getcwd function has been deprecated in favour of _getcwd. I think you could use it in this fashion.
Windows 上的 getcwd 函数已被弃用,取而代之的是 _getcwd。我认为你可以以这种方式使用它。
#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 );
}
回答by Octopus
This is from the cplusplus forum
这是来自cplusplus 论坛
On windows:
在窗户上:
#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 );
}
On Linux:
在 Linux 上:
std::string path = std::experimental::filesystem::current_path();
On HP-UX:
在 HP-UX 上:
#include <experimental/filesystem>
回答by Thorsten79
If you want a standard way without libraries: No. The whole concept of a directory is not included in the standard.
如果你想要一个没有库的标准方式:不。目录的整个概念不包含在标准中。
If you agree that some (portable) dependency on a near-standard lib is okay: Use Boost's filesystem libraryand ask for the initial_path().
如果您同意对近乎标准的库的某些(可移植)依赖是可以的:使用Boost 的文件系统库并请求initial_path()。
IMHO that's as close as you can get, with good karma (Boost is a well-established high quality set of libraries)
恕我直言,这是尽可能接近的,具有良好的业力(Boost 是一套完善的高质量库)
回答by Marqin
Filesystem TS is now a standard( and supported by gcc 5.3+ and clang 3.9+ ), so you can use current_path()
function from it:
文件系统 TS现在是一个标准(并由 gcc 5.3+ 和 clang 3.9+ 支持),因此您可以使用current_path()
它的功能:
int main(int argc, char* argv[])
{
std::string argv_str(argv[0]);
std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}
In gcc (5.3+) to include Filesystem you need to use:
在 gcc (5.3+) 中包含 Filesystem 你需要使用:
main
----> test
----> src
----> bin
and link your code with -lstdc++fs
flag.
并将您的代码与-lstdc++fs
标志链接起来。
If you want to use Filesystem with Microsoft Visual Studio, then read this.
如果您想将 Filesystem 与 Microsoft Visual Studio 一起使用,请阅读此.
回答by Sam Redway
I know it is very late at the day to throw an answer at this one but I found that none of the answers were as useful to me as my own solution. A very simple way to get the path from your CWD to your bin folder is like this:
我知道现在对这个问题给出答案已经很晚了,但我发现没有一个答案像我自己的解决方案一样对我有用。获取从 CWD 到 bin 文件夹的路径的一种非常简单的方法是这样的:
std::string pathToWrite = base + "/../test/test.log";
You can now just use this as a base for your relative path. So for example I have this directory structure:
您现在可以将其用作相对路径的基础。所以例如我有这个目录结构:
std::string base = argv[0].substr(0, argv[0].find_last_of("\"));
and I want to compile my source code to bin and write a log to test I can just add this line to my code.
我想将我的源代码编译到 bin 并编写一个日志来测试我可以将此行添加到我的代码中。
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
I have tried this approach on Linux using full path, alias etc. and it works just fine.
我已经在 Linux 上使用完整路径、别名等尝试过这种方法,并且效果很好。
NOTE:
笔记:
If you are on windows you should use a '\' as the file separator not '/'. You will have to escape this too for example:
如果您在 Windows 上,您应该使用“\”作为文件分隔符,而不是“/”。你也必须逃避这个,例如:
#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;
}
I think this should work but haven't tested, so comment would be appreciated if it works or a fix if not.
我认为这应该有效,但尚未测试,因此如果有效或无效则进行修复,我们将不胜感激。
回答by Adam Yaxley
On Windows the simplest way is to use the _get_pgmptr
function in stdlib.h
to get a pointer to a string which represents the absolute path to the executable, including the executables name.
在 Windows 上,最简单的方法是使用_get_pgmptr
in 函数stdlib.h
获取指向字符串的指针,该字符串表示可执行文件的绝对路径,包括可执行文件的名称。
回答by Michael Burr
No, there's no standard way. I believe that the C/C++ standards don't even consider the existence of directories (or other file system organizations).
不,没有标准的方法。我相信 C/C++ 标准甚至不考虑目录(或其他文件系统组织)的存在。
On Windows the GetModuleFileName()will return the full path to the executable file of the current process when the hModuleparameter is set to NULL. I can't help with Linux.
在 Windows 上,当hModule参数设置为NULL时,GetModuleFileName()将返回当前进程的可执行文件的完整路径。我对 Linux 无能为力。
Also you should clarify whether you want the current directory or the directory that the program image/executable resides. As it stands your question is a little ambiguous on this point.
此外,您应该阐明您想要当前目录还是程序映像/可执行文件所在的目录。就目前而言,您的问题在这一点上有点模棱两可。
回答by Jeremy Ruten
Maybe concatenate the current working directory with argv[0]? I'm not sure if that would work in Windows but it works in linux.
也许将当前工作目录与 argv[0] 连接起来?我不确定这是否适用于 Windows,但它适用于 linux。
For example:
例如:
##代码##When run, it outputs:
运行时,输出:
jeremy@jeremy-desktop:~/Desktop$ ./test
/home/jeremy/Desktop/./test
jeremy@jeremy-desktop:~/Desktop$ ./test
/home/jeremy/Desktop/./test
回答by Torbj?rn Gyllebring
For Win32 GetCurrentDirectoryshould do the trick.
对于 Win32 GetCurrentDirectory应该可以解决问题。