web-dev-qa-db-ja.com

別々の文字列からフルパス文字列を(安全に)構築する方法は?

C++にはPythonの関数os.path.join?基本的に、ファイルパスの2つ(またはそれ以上)の部分を組み合わせて、2つの部分が完全に適合することを心配する必要がないようにするものを探しています。 Qtにある場合、それもクールです。

基本的に、コードのデバッグに1時間かかりましたが、少なくともその一部はroot + filenameroot/ + filename、そして私は将来それを避けたいと思っています。

80
sas4740

QDir をチェックしてください:

QString path = QDir(dirPath).filePath(fileName);
37
Stephen Chu

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
94
user405725

@ user405725の回答(ブーストを使用しない)に似ており、@ ildjarnコメントでは、この機能は std :: experimental :: filesystem の一部として利用可能です。次のコードは、Microsoft Visual Studio 2015 Community Editionを使用してコンパイルします。

#include <iostream>
#include <filesystem>
namespace fs = std::experimental::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;
}
19
Shawn Blakesley

少なくともUnix/Linuxでは、パスの一部が既に/で終わっている場合でも、/でパスの一部を結合することは常に安全です。つまり、root/pathroot//path

この場合、本当に必要なのは/に参加することです。そうは言っても、複数のプラットフォームをサポートしているため、boost::filesystemを使用できるのであれば、それが良い選択であるという他の回答にも同意します。

8
frankc

Qtでこれを行いたい場合は、QFileInfoコンストラクターを使用できます。

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

Qtでは、Qt API(QFileQFileInfo)を使用するときに、コードで_/_を使用します。すべてのプラットフォームで正しいことを行います。パスをQt以外の関数に渡す必要がある場合、またはユーザーに表示するためにパスをフォーマットする場合は、QDir:toNativeSeparators()を使用します。例:

_QDir::toNativeSeparators( path );
_

_/_をネイティブの同等物(つまり、Windowsでは_\_)に置き換えます。他の方向はQDir::fromNativeSeparators()を介して行われます。

3
Frank Osterfeld

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
kainjow