2011-02-01 10 views
3

Je sais, ce n'est pas la meilleure idée d'ouvrir un fichier en le contraignant à être placé dans le même répertoire que le module exécuté. Mais, il y a un outil, on m'a ordonné de programmer, avec précision ces spécifications.Ouvrir le fichier relatif au module exécuté

Il existe un paramètre pour le chemin du fichier qui peut être le chemin absolu du fichier ou simplement le nom du fichier en supposant qu'il se trouve dans le répertoire en cours.

Je ne souhaite pas utiliser la fonction WinAPI GetCurrentDirectory pour conserver la portabilité. L'outil doit échouer si le fichier n'a pas pu être ouvert.

Habituellement, j'utilise boost :: filesystem comme bibliothèque d'E/S. Ainsi, je ne suis pas très familier avec std-library.

Ma première idée était de simplement passer le chemin du fichier à std :: ifstream :: open(). Mais il semble que cela ne fonctionne pas pour les chemins relatifs.

Que puis-je faire pour couvrir mes besoins?

+4

Vous commencez à parler de l'ouverture de fichiers qui résident dans le même répertoire que l'exécutable. Ensuite, vous parlez du répertoire actuel. Ce ne sont pas nécessairement identiques. En fait, je dirais même que c'est * rare * que le répertoire courant d'un programme de ligne de commande soit le même que celui du programme. S'il vous plaît clarifier ce dont vous avez vraiment besoin. –

Répondre

-3

Passez simplement le nom de fichier correspondant. Il sera pris par rapport au répertoire courant.

+1

Les répertoires actuels changent beaucoup trop sur Windows. La boîte de dialogue d'ouverture de fichier, par exemple, modifie le répertoire actuel sur vous, même à travers les threads. Vous devriez _never_ utiliser le répertoire courant sur win32 pour cette raison même. – bdonlan

+0

Voilà la question. Est-ce que std :: ifstream gère les chemins de fichiers relatifs ou non? – 0xbadf00d

+0

L'existence même de chemins relatifs ne fait pas partie de la norme C++ :) En général, il n'est pas portable de supposer que vous allez commencer dans le même répertoire que votre exécutable. Et ce n'est simplement pas vrai qui restera là. – bdonlan

3

Malheureusement, il n'existe pas de moyen facilement portable de le faire. En particulier, GetCurrentDirectory peut ne pas retourner le même répertoire que votre module exécutable - sous Windows, l'ouverture d'une boîte de sélection de fichier de dialogue commune entraînera la modification de votre répertoire courant! Sur d'autres plateformes, vous ne commencerez probablement pas du tout dans le même répertoire (vous n'aurez peut-être pas non plus d'accès en écriture, mais cela s'applique aussi aux fenêtres modernes ...)

Sur windows, in En général, vous devrez utiliser GetModuleFileName pour trouver l'emplacement de votre module, puis enlever la partie du nom de fichier. Sous Linux, appelez le readlink sur /proc/self/exe pour l'exécutable principal, ou munissez-vous de /proc/self/maps pour le mappage correspondant à votre segment de code pour une bibliothèque dynamique. Sur d'autres systèmes d'exploitation, je n'ai aucune idée.

+0

Vous avez raison. Je le sais déjà, mais comme je l'ai dit. J'espérais que je n'ai pas besoin d'utiliser WinAPI. – 0xbadf00d

+0

@ FrEEzE2046: Ecrivez votre propre fonction pour obtenir le nom du fichier, que vous implémentez différemment sous Windows et sous Linux (et même ailleurs). Ensuite, vous maintenez la portabilité via votre enveloppe fine. Cependant, en particulier sur les systèmes non-Windows, vous devriez envisager de meilleures idées; Vous semblez savoir que l'utilisation de l'emplacement de l'exécutable est une solution plutôt mauvaise de ce que vous avez indiqué dans la question. –

+0

@Fred Nurk - Conscrivant que le fichier se trouve dans le même dossier que l'exécutable fait partie de ma spécification. Ainsi, j'ai mentionné cela, mais ...;) – 0xbadf00d

Questions connexes