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

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


当前回答

只是我的两美分,但下面的代码在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还没有出现很多年。

其他回答

正如Minok提到的,在C标准或c++标准中没有指定这样的功能。例如,这被认为纯粹是特定于操作系统的特性,并且在POSIX标准中指定。

Thorsten79给出了很好的建议,它是Boost。文件系统库。然而,如果你不想让你的程序有任何二进制形式的链接时间依赖关系,这可能是不方便的。

我推荐的一个很好的替代方案是100%只包含标题的STLSoft c++库Matthew Wilson (c++必读书籍的作者)。PlatformSTL提供了对系统特定API的访问:Windows上的WinSTL和Unix上的UnixSTL,因此它是可移植的解决方案。所有特定于系统的元素都是使用特征和策略指定的,因此它是可扩展的框架。当然,还提供了文件系统库。

只是我的两美分,但下面的代码在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还没有出现很多年。

在POSIX平台上,可以使用getcwd()。

在Windows上,您可以使用_getcwd(),因为使用getcwd()已被弃用。

对于标准库,如果Boost对您来说足够标准,那么我会建议Boost::filesystem,但是他们似乎已经从建议中删除了路径规范化。您可能必须等到TR2可以随时获得完全标准的解决方案。

对于Win32, GetCurrentDirectory应该做到这一点。

也许连接当前工作目录与argv[0]?我不确定这是否适用于Windows,但它适用于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: ~ /桌面。美元/测试 /home/jeremy/Desktop/./test