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

发布于 2024-11-15 03:11:52 字数 224 浏览 2 评论 0原文

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

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

Does C++ have any equivalent to python's function os.path.join? Basically, I'm looking for something that combines two (or more) parts of a file path so that you don't have to worry about making sure the two parts fit together perfectly. If it's in Qt, that would be cool too.

Basically I spent an hour debugging some code and at least part of it was because root + filename had to be root/ + filename, and I'm looking to avoid that in the future.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

极度宠爱 2024-11-22 03:11:52

仅作为 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

Only as part of boost::filesystem library. Here is an example:

#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;
}

Here is an example of compiling and running (platform specific):

$ g++ ./test.cpp -o test -lboost_filesystem -lboost_system
$ ./test 
/tmp/foo.txt
韶华倾负 2024-11-22 03:11:52

此答案类似(但不使用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;
}

Similar to this answer (but not using boost), this functionality is available as part of std::filesystem. The following code compiles using Homebrew GCC 9.2.0_1 and using the flag --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;
}
醉南桥 2024-11-22 03:11:52

查看 QDir

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

Check out QDir for that:

QString path = QDir(dirPath).filePath(fileName);
坚持沉默 2024-11-22 03:11:52

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

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

At least in Unix / Linux, it's always safe to join parts of a path by /, even if some parts of the path already end in /, i.e. root/path is equivalent to root//path.

In this case, all you really need is to join things on /. That said, I agree with other answers that boost::filesystem is a good choice if it is available to you because it supports multiple platforms.

梦一生花开无言 2024-11-22 03:11:52

如果您想使用 Qt 执行此操作,可以使用 QFileInfo 构造函数:

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

If you want to do this with Qt, you can use QFileInfo constructor:

QFileInfo fi( QDir("/tmp"), "file" );
QString path = fi.absoluteFilePath();
╰つ倒转 2024-11-22 03:11:52

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

With C++11 and Qt you can do this:

QString join(const QString& v) {
    return v;
}

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

Usage:

QString path = join("/tmp", "dir", "file"); // /tmp/dir/file
紫罗兰の梦幻 2024-11-22 03:11:52

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

QDir::toNativeSeparators( path );

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

In Qt, just use / in code when using Qt API (QFile, QFileInfo). It will do the right thing on all platforms. If you have to pass a path to a non-Qt function, or want to format it for displaying it to the user, use QDir:toNativeSeparators() e.g.:

QDir::toNativeSeparators( path );

It will replace / by the native equivalent (i.e. \ on Windows). The other direction is done via QDir::fromNativeSeparators().

小霸王臭丫头 2024-11-22 03:11:52

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

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;
    }
}

Here is a very simple C++11 friendly alternative for the people who have neither Boost, Qt nor C++17 (taken from 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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文