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

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


当前回答

一个库解决方案(尽管我知道这不是要求的)。 如果你恰好使用Qt: QCoreApplication: applicationDirPath ()

其他回答

从c++ 11开始,使用实验文件系统,c++ 14- c++ 17以及使用正式文件系统。

application.h:

#pragma once

//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>

namespace std {
    namespace filesystem = experimental::filesystem;
}
#endif

std::filesystem::path getexepath();

application.cpp:

#include "application.h"
#ifdef _WIN32
#include <windows.h>    //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h>     //readlink
#endif

std::filesystem::path getexepath()
{
#ifdef _WIN32
    wchar_t path[MAX_PATH] = { 0 };
    GetModuleFileNameW(NULL, path, MAX_PATH);
    return path;
#else
    char result[PATH_MAX];
    ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
    return std::string(result, (count > 0) ? count : 0);
#endif
}

对于控制台的Windows系统,可以使用system(dir)命令。控制台提供目录等信息。在cmd下阅读有关dir命令的信息。但是对于类unix系统,我不知道…如果执行了该命令,请读取bash命令。Ls不显示目录…

例子:

int main()
{
    system("dir");
    system("pause"); //this wait for Enter-key-press;
    return 0;
}

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

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

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

不,没有标准的方法。我相信C/ c++标准甚至没有考虑目录(或其他文件系统组织)的存在。

在Windows上,当hModule参数设置为NULL时,GetModuleFileName()将返回当前进程可执行文件的完整路径。Linux我帮不上忙。

此外,您还应该明确您想要的是当前目录还是程序映像/可执行文件所在的目录。就目前情况来看,你的问题在这一点上有点模棱两可。

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

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

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