111 votes

Comment construire une chaîne de chemin complète (en toute sécurité) à partir de chaînes séparées ?

Le C++ a-t-il un équivalent de la fonction de Python ? os.path.join ? En gros, je cherche quelque chose qui combine deux (ou plusieurs) parties d'un chemin de fichier de sorte que vous n'ayez pas à vous soucier de vous assurer que les deux parties s'emboîtent parfaitement. Si c'est dans Qt, ce serait cool aussi.

En fait, j'ai passé une heure à déboguer du code et au moins une partie du problème était dû au fait que root + filename devait être root/ + filename et je cherche à éviter cela à l'avenir.

0 votes

Peut-être un parent éloigné : stackoverflow.com/questions/5772992/ (plus précisément, en ce qui concerne que La question est de savoir si boost complete )

115voto

Uniquement dans le cadre de Boost.Filesystem bibliothèque. Voici un exemple :

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

Voici un exemple de compilation et d'exécution (selon la plate-forme) :

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

1 votes

C'est également le cas dans TR2, qui sera probablement livré avec les compilateurs l'année prochaine.

0 votes

@ildjarn : Merci pour le permalien ! Je me suis toujours demandé s'il existait.

1 votes

@Vlad : Oui, ce n'est pas facile à découvrir, mais je déteste cliquer sur les liens de la doc Boost et me rendre compte tardivement que je suis en train de regarder une ancienne version, donc j'édite les liens spécifiques à la version des gens quand je les trouve. :-P

62voto

Shawn Blakesley Points 853

Similaire à @user405725 (mais n'utilisant pas boost), et mentionné par @ildjarn dans un commentaire, cette fonctionnalité est disponible dans le cadre de l'application std::filesystem . Le code suivant se compile en utilisant Homebrew GCC 9.2.0_1 et en utilisant le drapeau --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;
}

9 votes

À partir de C++17, il a été fusionné avec l'en-tête (non expérimental) <filesystem>. Voir fr.cppreference.com/w/cpp/filesystem .

0 votes

Cela fonctionnerait-il si nous avions "/tmp/" ?

1 votes

Merci beaucoup, cette réponse est une voie à suivre dans le cas où c++ 17 est disponible sur le projet.

52voto

Stephen Chu Points 8440

Vérifiez QDir pour ça :

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

4 votes

Attention, Qt est sous licence GPL. Cela peut être un obstacle pour de nombreuses utilisations.

7 votes

@RustyX c'est LGPL, pour être précis.

10voto

frankc Points 6014

Au moins sous Unix / Linux, il est toujours sûr de joindre des parties d'un chemin par / même si certaines parties du chemin se terminent déjà en / c'est-à-dire root/path est équivalent à root//path .

Dans ce cas, tout ce dont vous avez besoin est de joindre les choses sur / . Cela dit, je suis d'accord avec les autres réponses que boost::filesystem est un bon choix s'il est à votre disposition, car il prend en charge plusieurs plateformes.

2 votes

QT est agnostique au séparateur de chemin. Si vous imprimez le chemin absolu d'un fichier sous Windows, la sortie est "C:/Users/Name/MyFile.txt" avec le séparateur / (unix). boost::filesystem est génial mais, à mon avis, si le projet est basé sur Qt, il n'y a pas besoin d'ajouter une dépendance pour la bibliothèque boost.

7voto

LoSciamano Points 869

Si vous voulez faire cela avec Qt, vous pouvez utiliser QFileInfo constructeur :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X