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


89

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

基本的に、コードのデバッグに1時間を費やしましたが、少なくともその一部はでroot + filenameなければならないためでしたroot/ + filename。将来はそれを回避したいと考えています。


おそらく遠く離れて関連している:stackoverflow.com/questions/5772992/…(特に、その質問に関連しいるのはboost'sですcomplete
オービットのライトネスレース

回答:



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のドキュメントリンクをクリックするのが嫌いで、ついに古いバージョンを探していることに気づきました。:-P
ildjarn

1
@ildjarn:これはうまく機能しているようです...しかし、彼らがサイトまたは指定されたライブラリのドキュメントについて何かを変更するまで待ちます。それ以降、バージョン固有のリンクを残すよりも悪いです。
Fred Nurk

1
@Fred:明らかに、機能や質問がバージョン固有のものである場合は、URLを変更しません。この場合はそうではないので、私はそうしました。
ildjarn 2011年

1
@ildjarn:特定のライブラリが将来変更される内容をどのように予測して、編集したすべての回答が将来のすべてのバージョンで意味があるかを知ることができますか?
Fred Nurk 2011年

24

同様に、@ user405725の答え(ただし、ブーストを使用していない)、と言及@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 2018

9

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

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


2
QTはパス区切り文字に依存しません。Windowsでファイルの絶対パスを出力する場合、出力は "C:/Users/Name/MyFile.txt"であり、/(UNIX)区切り記号が付いています。boost :: filesystemは素晴らしいですが、私の意見では、プロジェクトがQtベースの場合、boostライブラリの依存関係を追加する必要はありません。
LoSciamano

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()ます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.