(如果没有平台/文件系统无关的方法,也欢迎在Windows和Linux上针对特定文件系统的建议。)
char pBuf[256];
size_t len = sizeof(pBuf);
Windows:
int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;
Linux:
int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;
/proc
的代码时,我的心情会稍稍凋谢。全世界并不只有Linux这一个平台,即使在这个平台上,/proc
也应该被视为易受版本、架构等影响而改变的东西。 - asveikauargv[0]
,但这可能会被启动你的进程所伪造。 - asveikauchar pBuf[256]; size_t len = sizeof(pBuf);
以使解决方案更加清晰。 - charles.cc.hsu如果在程序启动时获取当前目录,则可以有效地获得程序启动的目录。将该值存储在变量中,并在程序的后续部分中引用它。这与包含当前可执行程序文件的目录不同。它并不一定是相同的目录;如果有人从命令提示符运行该程序,则程序将从命令提示符的当前工作目录运行,即使程序文件位于其他位置也是如此。
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);
这是来自于C++论坛
在 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 );
}
返回值: main()函数入口时的current_path()。
而current_path()的行为类似于POSIX getcwd()。这并不是提问者所要求的内容。 - Jonathan Leffler我知道这个回答很晚了,但是我发现没有一个回答对我有用,所以我找到了自己的解决方案。获取从当前工作目录到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
我想将我的源代码编译成二进制文件,并写入一个日志以测试。我只需要在我的代码中添加这一行。
std::string pathToWrite = base + "/../test/test.log";
我已经在Linux上使用了完整路径、别名等尝试了这种方法,效果非常好。
注意:
如果你在Windows上,应该使用 '\' 作为文件分隔符而不是 '/'. 你也需要将它转义,例如:
std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));
我认为这应该可行,但尚未测试,因此如果它起作用,请留下评论;如果不起作用,请提供修复建议。
argv[0]
是一个非常好的想法,但不幸的是,在 Linux 上我得到的是 "./my_executable_name" 或 "./make/my_executable_name"。基本上,我得到的取决于我如何启动它。 - Xeverous文件系统TS 现在是一个标准(并且由gcc 5.3+和clang 3.9+支持),因此您可以使用它的current_path()
函数:
std::string path = std::experimental::filesystem::current_path();
在gcc (5.3+)中,要包含Filesystem,您需要使用:
#include <experimental/filesystem>
并使用-lstdc++fs
标志将您的代码链接。
如果您想在Microsoft Visual Studio中使用文件系统,请阅读此内容。
在Windows上,最简单的方法是使用 stdlib.h
中的_get_pgmptr
函数获取指向表示可执行文件的绝对路径(包括可执行文件的名称)的字符串的指针。
char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
没有标准的方法。我相信C/C++标准甚至不考虑目录(或其他文件系统组织)的存在。
在Windows上,当hModule参数设置为NULL时,GetModuleFileName()将返回当前进程可执行文件的完整路径。我无法提供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
如果是Win32系统,可以使用GetCurrentDirectory函数来完成。
argv [0]
中提取路径,否则该技术将非常依赖于操作系统。 - David R Tribble#include <windows.h>
时,Windows会自动将可执行文件路径的char*
存储在_pgmptr
中。如果你只在Windows上工作,就不需要调用额外的函数或假设无用信息。 - rsethc_pgmptr
的评论。MSDN文档说明_pgmptr
和_wpgmptr
变量已被弃用,应该使用函数_get_pgmptr(char**)
或_get_wpgmptr(wchar_t**)
代替。MSDN - Hydranix