是否有一种平台不可知和文件系统不可知的方法来获取程序运行的目录的完整路径?不要与当前工作目录混淆。(请不要推荐库,除非它们是像clib或STL这样的标准库。)

(如果没有平台/文件系统不可知的方法,也欢迎在Windows和Linux中针对特定文件系统工作的建议。)


当前回答

当前.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;

其他回答

在Windows上,最简单的方法是使用stdlib.h中的_get_pgmptr函数来获取一个指向字符串的指针,该字符串表示可执行文件的绝对路径,包括可执行文件的名称。

char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe

这是来自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 );
}

Boost Filesystem的initial_path()的行为类似于POSIX的getcwd(),它们本身都不能满足您的需要,但是将argv[0]附加到它们中的任何一个都可以做到这一点。

您可能会注意到,结果并不总是很漂亮——您可能会得到/foo/bar/../ baz/a这样的东西。Out或/foo/bar//baz/a。out,但我相信它总是会产生一个有效的路径,该路径命名可执行文件(注意,路径中连续的斜杠被折叠为一个)。

我以前用envp (main()的第三个参数)写了一个解决方案,它在Linux上有效,但在Windows上似乎行不通,所以我基本上是在推荐和其他人以前一样的解决方案,但附加了为什么它实际上是正确的,即使结果并不漂亮。

在stdlib.h中像这样使用realpath():

char *working_dir_path = realpath(".", NULL);

下面的操作在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