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


89

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

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


可能遥远相关:stackoverflow.com/questions/5772992/…(特别是,与问题有关的问题是升压的complete
Lightness Races in Orbit

Answers:


44

检查一下QDir

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

3
注意,Qt是GPL。可能会成为很多用途的破坏者。
rustyx

2
@RustyX,确切地说是LGPL。
Pa_

97

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

1
TR2中也有此功能,它可能会在明年与编译器一起发布。
ildjarn 2011年

1
@Vlad:是的,它不容易被发现,但是我讨厌单击Boost doc链接,但后来才意识到我正在查看一个旧版本,因此当我遇到人们的特定于版本的链接时,我会对其进行编辑。:-P
ildjarn 2011年

1
@ildjarn:现在看来效果很好...但是请等到他们更改有关给定库的网站或文档的内容。这比从那时起留下特定于版本的链接更糟。
Fred Nurk 2011年

1
@Fred:显然,如果功能或问题恰好是特定于版本的,那么我不会更改URL。在这种情况下,不是,所以我做到了。
ildjarn 2011年

1
@ildjarn:您如何预测给定库在将来会发生什么变化,以便您知道您编辑的所有答案对于将来的所有版本是否有意义?
Fred Nurk 2011年

24

类似@ user405725的答案(而不是使用boost),并提到@ildjarn的评论,这个功能可作为的一部分的std ::文件系统。以下代码使用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;
}

4
从C ++ 17开始,它被合并到(非实验性的)<filesystem>标头中。请参阅en.cppreference.com/w/cpp/filesystem
Eli_B

9

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

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


2
QT与路径分隔符无关。如果在Windows上打印文件的绝对路径,则输出为带有/(unix)分隔符的“ C:/Users/Name/MyFile.txt”。boost :: filesystem很棒,但是我认为,如果该项目基于Qt,则无需为boost库添加依赖项。
LoSciamano 2011年

7

如果要使用Qt进行此操作,可以使用QFileInfo构造函数:

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

4

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

3

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

QDir::toNativeSeparators( path );

它将/被等效的本机替代(例如,\在Windows上)。另一个方向是通过QDir::fromNativeSeparators()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.