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

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


当前回答

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

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

其他回答

只是迟来的堆砌在这里,…

没有标准的解决方案,因为这些语言不知道底层文件系统,所以正如其他人所说,基于目录的文件系统的概念超出了c / c++语言的范围。

on top of that, you want not the current working directory, but the directory the program is running in, which must take into account how the program got to where it is - ie was it spawned as a new process via a fork, etc. To get the directory a program is running in, as the solutions have demonstrated, requires that you get that information from the process control structures of the operating system in question, which is the only authority on this question. Thus, by definition, its an OS specific solution.

对于相对路径,我是这样做的。我知道这个问题的年代久远,我只是想提供一个在大多数情况下都适用的更简单的答案:

假设你有一个这样的路径:

"path/to/file/folder"

出于某种原因,在eclipse中构建的linux可执行文件可以很好地使用它。然而,如果给窗口一个这样的路径来工作,它会变得非常混乱!

如上所述,有几种方法可以获得可执行文件的当前路径,但我发现在大多数情况下最简单的方法是将其附加到路径的FRONT:

"./path/to/file/folder"

只是补充”。/“应该让你整理好!”:)然后你可以从任何你想要的目录开始加载,只要它是可执行文件本身。

编辑:如果您试图从code::blocks启动可执行文件,这将不起作用,如果这是正在使用的开发环境,由于某些原因,code::blocks不能正确加载东西…: D

EDIT2:我发现的一些新情况是,如果您在代码中指定一个像这样的静态路径(假设示例。数据是你需要加载的东西):

"resources/Example.data"

如果你从实际目录中启动你的应用程序(或者在Windows中,你做一个快捷方式,并将工作目录设置为你的应用程序目录),那么它就会像这样工作。 在调试与缺少资源/文件路径相关的问题时,请记住这一点。(特别是在IDE中,当从IDE启动build exe时设置了错误的工作目录)

这个问题是15年前问的,所以现在现有的答案是不正确的。如果你使用的是c++ 17或更高版本,现在的解决方案非常简单:

#include <filesystem>

std::cout << std::filesystem::current_path();

更多信息请参见cppreference.com。

只是我的两美分,但下面的代码在c++ 17中不能移植吗?

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
}

至少在Linux上对我有用。

根据前面的想法,我现在有:

std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");

与实现:

fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
{
    static auto exe_parent_path = fs::path(exe_path).parent_path();
    return exe_parent_path / filename;
}

main()中的初始化技巧:

(void) prepend_exe_path("", argv[0]);

感谢@Sam Redway的argv[0]想法。当然,我知道当OP提出这个问题时,c++ 17还没有出现很多年。

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