【问题标题】:How to build a full path string (safely) from separate strings?如何从单独的字符串(安全地)构建完整路径字符串?
【发布时间】:2011-09-11 23:14:32
【问题描述】:

C++ 是否有任何等效于 python 的函数os.path.join?基本上,我正在寻找将文件路径的两个(或多个)部分组合在一起的东西,这样您就不必担心确保这两个部分完美地结合在一起。如果它在 Qt 中,那也很酷。

基本上我花了一个小时调试一些代码,至少部分原因是因为root + filename 必须是root/ + filename,我希望将来避免这种情况。

【问题讨论】:

标签: c++ qt filepath


【解决方案1】:

仅作为Boost.Filesystem 库的一部分。这是一个例子:

#include <iostream>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

int main ()
{
    fs::path dir ("/tmp");
    fs::path file ("foo.txt");
    fs::path full_path = dir / file;
    std::cout << full_path << std::endl;
    return 0;
}

这是编译和运行的示例(特定于平台):

$ g++ ./test.cpp -o test -lboost_filesystem -lboost_system
$ ./test 
/tmp/foo.txt

【讨论】:

  • 这也在 TR2 中,很可能在明年开始与编译器一起发布。
  • @Vlad :是的,它不容易被发现,但我讨厌点击 Boost 文档链接,然后才意识到我正在查看旧版本,所以当我遇到时,我会编辑人们的特定于版本的链接他们。 :-P
  • @ildjarn:现在看来效果很好……但要等到他们更改了有关站点或给定库的文档的某些内容。这比从此离开特定版本的链接更糟糕。
  • @Fred :显然,如果功能或问题恰好是特定于版本的,我不会更改 URL。在这种情况下,它不是,所以我做了。
  • @ildjarn:您如何预测给定库将来会发生什么变化,以便知道您编辑的所有答案是否对所有未来版本都有意义?
【解决方案2】:

请查看QDir

QString path = QDir(dirPath).filePath(fileName);

【讨论】:

  • 请注意 Qt 是 GPL。可能会成为许多用途的交易破坏者。
  • @RustyX 准确地说是 LGPL。
  • 我喜欢这个答案,不用担心字符串和连接,让框架来解决。
【解决方案3】:

类似于 @user405725 的回答(但不使用 boost),并且由 @ildjarn 在评论中提到,此功能可作为 std::filesystem 的一部分使用.以下代码使用 Homebrew GCC 9.2.0_1 并使用标志 --std=c++17 进行编译:

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

int main() 
{
    fs::path dir ("/tmp");
    fs::path file ("foo.txt");
    fs::path full_path = dir / file;
    std::cout << full_path << std::endl;
    return 0;
}

【讨论】:

  • 从 C++17 开始,它被合并到(非实验性的) 头文件中。见en.cppreference.com/w/cpp/filesystem
  • 非常感谢,如果项目中可以使用 c++ 17,这个答案是一种方法。
  • 在我的情况下,它只是直接加入它们(而不是在它们之间放置 /\
【解决方案4】:

至少在 Unix / Linux 中,通过/ 连接部分路径总是安全的,即使路径的某些部分已经以/ 结束,即root/path 等同于root//path

在这种情况下,您真正​​需要的只是加入/。也就是说,我同意其他答案,即如果您可以使用 boost::filesystem 是一个不错的选择,因为它支持多个平台。

【讨论】:

  • QT 与路径分隔符无关。如果您在 Windows 上打印文件的绝对路径,则输出为带有 /(unix)分隔符的“C:/Users/Name/MyFile.txt”。 boost::filesystem 很棒,但在我看来,如果项目是基于 Qt 的,则无需为 boost 库添加依赖项。
【解决方案5】:

如果你想用 Qt 做到这一点,你可以使用QFileInfo 构造函数:

QFileInfo fi( QDir("/tmp"), "file" );
QString path = fi.absoluteFilePath();

【讨论】:

    【解决方案6】:

    使用 C++11 和 Qt,您可以这样做:

    QString join(const QString& v) {
        return v;
    }
    
    template<typename... Args>
    QString join(const QString& first, Args... args) {
        return QDir(first).filePath(join(args...));
    }
    

    用法:

    QString path = join("/tmp", "dir", "file"); // /tmp/dir/file
    

    【讨论】:

      【解决方案7】:

      在 Qt 中,使用 Qt API 时只需在代码中使用 /QFileQFileInfo)。它将在所有平台上做正确的事情。如果您必须将路径传递给非 Qt 函数,或者想要对其进行格式化以将其显示给用户,请使用 QDir:toNativeSeparators() 例如:

      QDir::toNativeSeparators( path );
      

      它将用原生等效项替换 /(即 Windows 上的 \)。另一个方向是通过QDir::fromNativeSeparators() 完成的。

      【讨论】:

        猜你喜欢
        • 2020-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多