如何从单独的字符串(安全地)构建完整路径字符串?

问题描述 投票:0回答:8

C++ 是否有相当于 python 的函数

os.path.join
?基本上,我正在寻找结合文件路径的两个(或更多)部分的东西,这样您就不必担心确保这两个部分完美地配合在一起。如果是在 Qt 中,那就太酷了。

基本上我花了一个小时调试一些代码,至少部分是因为

root + filename
必须是
root/ + filename
,我希望将来避免这种情况。

c++ qt filepath
8个回答
116
投票

仅作为

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

74
投票

这个答案类似(但不使用

boost
),此功能作为
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;
}

52
投票

查看

QDir

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

10
投票

至少在 Unix / Linux 中,通过

/
连接路径的各个部分始终是安全的,即使路径的某些部分已经以
/
结尾,即
root/path
相当于
root//path

在这种情况下,您真正需要的只是加入

/
上的内容。也就是说,我同意其他答案,即如果您可以使用,
boost::filesystem
是一个不错的选择,因为它支持多个平台。


7
投票

如果你想用 Qt 来做到这一点,你可以使用

QFileInfo
构造函数:

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

5
投票

使用 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

4
投票

在Qt中,使用Qt API时只需在代码中使用

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

QDir::toNativeSeparators( path );

它将用本机等效项替换

/
(即 Windows 上的
\
)。另一个方向是通过
QDir::fromNativeSeparators()
完成的。


2
投票

对于既没有 Boost、Qt 也没有 C++17 的人来说,这是一个非常简单的 C++11 友好替代方案(摘自 here)。

std::string pathJoin(const std::string& p1, const std::string& p2)
{
    char sep = '/';
    std::string tmp = p1;

#ifdef _WIN32
    sep = '\\';
#endif

    // Add separator if it is not included in the first path:
    if (p1[p1.length() - 1] != sep) {
        tmp += sep;
        return tmp + p2;
    } else {
        return p1 + p2;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.