Ayrı dizelerden tam yol dizesi (güvenli bir şekilde) nasıl oluşturulur?


91

C ++ 'nın python işlevine herhangi bir eşdeğeri var os.path.joinmı? Temel olarak, bir dosya yolunun iki (veya daha fazla) bölümünü birleştiren bir şey arıyorum, böylece iki parçanın birbirine mükemmel şekilde uyduğundan emin olmak için endişelenmenize gerek kalmaz. Qt'de ise, bu da harika olurdu.

Temelde bazı kod hata ayıklama bir saat geçirdim ve bunu nedeniyle azından kısmen oldu root + filenamegerekiyordu root/ + filenameve ben gelecekte bu önlemek için arıyorum.


Muhtemelen uzaktan ilişkili: stackoverflow.com/questions/5772992/… (özellikle, bu soruyla ilgili olarak ,complete
artışlar

Yanıtlar:


45

Bunun için QDir'e göz atın :

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

3
Qt'nin GPL olduğuna dikkat edin. Birçok kullanım için bir anlaşma kırıcı olabilir.
rustyx

4
@RustyX, kesin olmak gerekirse LGPL'dir.
Pa_

100

Yalnızca Boost.Filesystem kitaplığının bir parçası olarak . İşte bir örnek:

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

İşte bir derleme ve çalıştırma örneği (platforma özel):

$ g++ ./test.cpp -o test -lboost_filesystem -lboost_system
$ ./test 
/tmp/foo.txt

1
Bu, önümüzdeki yıl derleyicilerle birlikte gönderilmeye başlanması muhtemel TR2'de de geçerli.
ildjarn

1
@Vlad: Evet, kolayca keşfedilebilir değil, ancak Boost doc bağlantılarına tıklamadan ve geç bir şekilde eski bir sürüme baktığımı fark etmekten nefret ediyorum, bu yüzden karşılaştığımda insanların sürüme özgü bağlantılarını düzenliyorum. :-P
ildjarn

1
@ildjarn: Bu şimdi harika çalışıyor gibi görünüyor ... ama site veya verilen kitaplık için dokümanlar hakkında bir şeyler değiştirene kadar bekleyin. O andan itibaren sürüme özgü bağlantıyı bırakmaktan daha kötüdür.
Fred Nurk

1
@Fred: Açıkçası, işlevsellik veya soru sürüme özgü olursa, URL'yi değiştirmem. Bu durumda değil, ben de yaptım.
ildjarn

1
@ildjarn: Düzenlediğiniz tüm yanıtların gelecekteki tüm sürümler için anlamlı olup olmayacağını bilmesi için belirli bir kitaplığın gelecekte nelerin değişeceğini nasıl tahmin edersiniz?
Fred Nurk

24

@ User405725'in cevabına benzer (ancak artırmayı kullanmayan) ve @ildjarn tarafından bir yorumda bahsedilen bu işlevsellik std :: dosya sisteminin bir parçası olarak mevcuttur . Aşağıdaki kod Homebrew GCC 9.2.0_1 ve bayrak kullanılarak derlenir --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'den itibaren, bu (deneysel olmayan) <filesystem> başlığında birleştirildi. Bkz. En.cppreference.com/w/cpp/filesystem .
Eli_B

9

En azından Unix / Linux'ta, yolun /bazı kısımları zaten bitse de /, yani root/patheşdeğer olsa bile , bir yolun parçalarını birleştirmek her zaman güvenlidir root//path.

Bu durumda, gerçekten ihtiyacınız olan tek şey şeylere katılmaktır /. Bununla birlikte boost::filesystem, birden fazla platformu desteklediği için sizin için mevcutsa iyi bir seçim olan diğer yanıtlara katılıyorum .


2
QT, yol ayırıcıya göre agnostiktir. Windows'ta bir dosyanın mutlak yolunu yazdırırsanız, çıktı / (unix) ayırıcısı ile "C: /Users/Name/MyFile.txt" olur. boost :: dosya sistemi harika, ancak bence proje Qt tabanlıysa, destek kitaplığı için bir bağımlılık eklemeye gerek yok.
LoSciamano

7

Bunu Qt ile yapmak istiyorsanız, yapıcıyı kullanabilirsiniz QFileInfo:

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

4

C ++ 11 ve Qt ile bunu yapabilirsiniz:

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

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

Kullanım:

QString path = join("/tmp", "dir", "file"); // /tmp/dir/file

3

Qt'de, /Qt API ( QFile, QFileInfo) kullanırken kodda kullanın . Tüm platformlarda doğru olanı yapacak. Qt olmayan bir işleve yol iletmeniz gerekiyorsa veya bunu kullanıcıya görüntülemek için biçimlendirmek istiyorsanız, QDir:toNativeSeparators()örneğin:

QDir::toNativeSeparators( path );

Bu yerini alacak /yerli eşdeğeri (yani tarafından \Windows üzerinde). Diğer yön üzerinden yapılır QDir::fromNativeSeparators().

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.