web-dev-qa-db-fra.com

Comment utiliser des objets fstream avec un chemin relatif?

Dois-je toujours spécifier un chemin absolu pour les objets instanciés à partir de std::fstream classe? En d'autres termes, existe-t-il un moyen de leur spécifier un chemin d'accès relatif, tel que le chemin du projet?

24
user336359

Vous pouvez également utiliser des chemins relatifs. Mais ils sont relatifs à l'environnement à partir duquel vous appelez votre exécutable.

Cela dépend du système d'exploitation, mais tous les principaux systèmes se comportent plus ou moins le même AFAIK.

Exemple Windows:

// File structure:
c:\folder\myprogram.exe
c:\myfile.txt

// Calling command from folder
c:\folder > myprogram.exe

Dans l'exemple ci-dessus, vous pouvez accéder à monfichier.txt avec "c: /myfile.txt" ou "../myfile.txt". Si myprogram.exe a été appelé à partir de la racine c:\ seul le chemin absolu fonctionnerait, mais "monfichier.txt" fonctionnerait à la place.

Comme Rob Kennedy l'a dit dans les commentaires, il n'y a vraiment rien de spécial à propos des chemins concernant fstream. Mais voici un exemple de code utilisant un chemin relatif:

#include <fstream>
int main() {
    std::ifstream ifs("../myfile.txt");
    ... // Do something sensible with the file
}
17
Kleist

Si vous avez un .exe fichier exécuté à partir de C:\Users\Me et vous voulez écrire un fichier dans C:\Users\Me\You\text.txt, alors tout ce que vous devez faire est d'ajouter l'opérateur de chemin actuel ., donc:

std::ifstream ifs(".\\you\\myfile.txt");

marchera

11
Samer

Vous pouvez utiliser des chemins relatifs. Ils sont traités de la même manière que les chemins relatifs pour toute autre opération de fichier, comme fopen; à cet égard, fstream n'a rien de spécial.

La manière exacte dont ils sont traités est définie par l'implémentation; ils seront généralement interprétés par rapport au répertoire de travail actuel de votre processus, qui n'est pas nécessairement le même que le répertoire dans lequel se trouve le fichier exécutable de votre programme. Certains systèmes d'exploitation peuvent également fournir un seul répertoire de travail partagé par all threads, vous pouvez donc obtenir des résultats inattendus si un thread modifie le répertoire de travail en même temps qu'un autre thread essaie d'utiliser un chemin relatif.

2
Rob Kennedy

Supposons que vous avez un dossier src directement sous le répertoire de votre projet et que le dossier src contient un autre tmp_folder dossier contenant un fichier txt nommé readMe.txt. Ainsi, le fichier txt peut être lu de cette façon

std::ifstream fin("../src/tmp_folder/readMe.txt");
1
Martin

Le comportement est spécifique au système d'exploitation. Par conséquent, la meilleure façon de gérer cette IMHO est d'en faire le problème de quelqu'un d'autre. Lisez le chemin du fichier à ouvrir sous forme de chaîne de l'utilisateur (par exemple: argument de ligne de commande, fichier de configuration, variable env, etc.) puis passez cette chaîne directement au constructeur de fstream. Documentez que c'est ainsi que se comporte votre programme.

J'ai écrit plus sur la manipulation de chemin ici: https://stackoverflow.com/a/40980510/2345997

1
user1976

Vous pouvez spécifier un chemin par rapport à répertoire courant. Sous Windows, vous pouvez appeler GetCurrentDirectory pour récupérer répertoire actuel ou appeler SetCurrentDirectory pour définir répertoire actuel. Certaines fonctions CRT sont également disponibles.

0
0902horn

Sous Linux également:

// main.cpp
int main() {
    ifstream myFile("../Folder/readme.txt");
    // ...
}

En supposant que la structure des dossiers ressemble à ceci:

/usr/Douments/dev/MyProject/main.cpp/usr/Documents/dev/MyProject/Folder/readme.txt

0
A-Sharabiani