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

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


当前回答

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

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

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

其他回答

如果你想要一种没有库的标准方式:不。标准中没有包含目录的整个概念。

如果您同意对接近标准库的某些(可移植的)依赖是可以的:使用Boost的文件系统库并请求initial_path()。

恕我直言,这是你能得到的最接近的结果,并且有良好的因果报应(Boost是一套完善的高质量库)

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

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

"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时设置了错误的工作目录)

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

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

我知道现在回答这个问题已经很晚了,但我发现没有一个答案像我自己的解决方案那样对我有用。一个非常简单的方法来获取路径从你的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("\\"));

我认为这应该工作,但还没有测试,所以评论将是感激如果它工作或修复如果不是。

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