Existe-t-il une méthode indépendante de la plate-forme et indépendante du système de fichiers pour obtenir le chemin complet du répertoire à partir duquel un programme s'exécute à l'aide de C / C ++? À ne pas confondre avec le répertoire de travail actuel. (Veuillez ne pas suggérer de bibliothèques à moins qu'elles ne soient standard comme clib ou STL.)
(S'il n'y a pas de méthode indépendante de la plate-forme / du système de fichiers, les suggestions qui fonctionnent sous Windows et Linux pour des systèmes de fichiers spécifiques sont également les bienvenues.)
c++
c
working-directory
Ashwin Nanjappa
la source
la source
argv[0]
, la technique dépendra beaucoup du système d'exploitation.#include <windows.h>
, Windows place automatiquement unchar*
dans le chemin exécutable dans_pgmptr
. Vous n'avez pas besoin d'appeler des fonctions supplémentaires ou d'assumer le courrier indésirable si vous travaillez uniquement sur Windows._pgmptr
. La documentation MSDN indique que les variables_pgmptr
et_wpgmptr
sont obsolètes et que vous devez utiliser la fonction_get_pgmptr(char**)
ou à la_get_wpgmptr(wchar_t**)
place. MSDNRéponses:
Voici le code pour obtenir le chemin d'accès complet à l'application en cours d'exécution:
Les fenêtres:
Linux:
la source
/proc
partie de moi, il meurt un peu. Tout le monde n'est pas Linux, et même sur cette seule plate-forme/proc
devrait être considérée sous réserve de changer de version en version, d'arc en arc, etc.char pBuf[256]; size_t len = sizeof(pBuf);
pour laisser la solution plus clairement.Si vous récupérez le répertoire courant lors du premier démarrage de votre programme, vous disposez effectivement du répertoire à partir duquel votre programme a été démarré. Stockez la valeur dans une variable et faites-y référence plus tard dans votre programme. Ceci est distinct du répertoire qui contient le fichier programme exécutable actuel . Ce n'est pas nécessairement le même répertoire; si quelqu'un exécute le programme à partir d'une invite de commandes, le programme est exécuté à partir du répertoire de travail actuel de l'invite de commandes, même si le fichier du programme réside ailleurs.
getcwd est une fonction POSIX et prise en charge prête à l'emploi par toutes les plates-formes compatibles POSIX. Vous n'auriez rien à faire de spécial (à part inclure les bons en-têtes unistd.h sous Unix et direct.h sous Windows).
Puisque vous créez un programme C, il sera lié à la bibliothèque d'exécution c par défaut qui est liée à TOUS les processus du système (les exceptions spécialement conçues sont évitées) et il inclura cette fonction par défaut. Le CRT n'est jamais considéré comme une bibliothèque externe car il fournit l'interface standard de base compatible avec le système d'exploitation.
Sous Windows, la fonction getcwd a été déconseillée au profit de _getcwd. Je pense que vous pouvez l'utiliser de cette façon.
la source
C'est du forum cplusplus
Sur les fenêtres:
Sous Linux:
Sur HP-UX:
la source
error: cannot convert 'char*' to 'LPWCH {aka wchar_t*}' for argument '2' to 'DWORD GetModuleFileNameW(HMODULE, LPWCH, DWORD)'
lors de la compilation avec MinGW.Si vous voulez une méthode standard sans bibliothèques: Non. Le concept entier d'un répertoire n'est pas inclus dans la norme.
Si vous acceptez qu'une certaine dépendance (portable) à une bibliothèque proche du standard est acceptable: utilisez la bibliothèque de système de fichiers de Boost et demandez initial_path () .
IMHO qui est aussi proche que possible, avec un bon karma (Boost est un ensemble de bibliothèques de haute qualité bien établi)
la source
Filesystem TS est maintenant un standard (et pris en charge par gcc 5.3+ et clang 3.9+), vous pouvez donc utiliser la
current_path()
fonction à partir de celui-ci:Dans gcc (5.3+) pour inclure le système de fichiers, vous devez utiliser:
et liez votre code avec le
-lstdc++fs
drapeau.Si vous souhaitez utiliser le système de fichiers avec Microsoft Visual Studio, lisez ceci .
la source
1-2) Returns the absolute path of the current working directory, obtained as if by POSIX getcwd. (2) returns path() if error occurs.
Downvoted, car l'OP demande spécifiquement le chemin actuel de l'exécutable plutôt que le répertoire de travail actuel.Je sais qu'il est très tard dans la journée pour répondre à celle-ci, mais j'ai trouvé qu'aucune des réponses ne m'était aussi utile que ma propre solution. Un moyen très simple d'obtenir le chemin de votre CWD vers votre dossier bin est comme ceci:
Vous pouvez maintenant simplement l'utiliser comme base pour votre chemin relatif. Ainsi, par exemple, j'ai cette structure de répertoires:
et je veux compiler mon code source dans le bac et écrire un journal pour tester je peux simplement ajouter cette ligne à mon code.
J'ai essayé cette approche sur Linux en utilisant le chemin complet, l'alias, etc. et cela fonctionne très bien.
REMARQUE:
Si vous êtes sous Windows, vous devez utiliser un «\» comme séparateur de fichier et non «/». Vous devrez également y échapper par exemple:
Je pense que cela devrait fonctionner mais ne l'ont pas testé, donc un commentaire serait apprécié s'il fonctionne ou un correctif sinon.
la source
argv[0]
est une très bonne idée, mais malheureusement ce que je reçois sur Linux est "./my_executable_name" ou "./make/my_executable_name". Fondamentalement, ce que j'obtiens dépend complètement de la façon dont je le lanceNon, il n'y a pas de moyen standard. Je crois que les normes C / C ++ ne considèrent même pas l'existence de répertoires (ou d'autres organisations de système de fichiers).
Sous Windows, GetModuleFileName () renverra le chemin d'accès complet au fichier exécutable du processus en cours lorsque le paramètre hModule est défini sur NULL . Je ne peux pas m'empêcher avec Linux.
Vous devez également préciser si vous voulez le répertoire actuel ou le répertoire dans lequel réside l'image / l'exécutable du programme. En l'état, votre question est un peu ambiguë sur ce point.la source
Sous Windows, le moyen le plus simple consiste à utiliser la
_get_pgmptr
fonction instdlib.h
pour obtenir un pointeur sur une chaîne qui représente le chemin absolu vers l'exécutable, y compris le nom de l'exécutable.la source
Peut-être concaténer le répertoire de travail actuel avec argv [0]? Je ne sais pas si cela fonctionnerait sous Windows mais cela fonctionne sous Linux.
Par exemple:
Lorsqu'il est exécuté, il génère:
la source
Pour Win32, GetCurrentDirectory devrait faire l'affaire.
la source
Vous ne pouvez pas utiliser argv [0] à cet effet, il contient généralement le chemin d'accès complet à l'exécutable, mais pas nécessairement - le processus peut être créé avec une valeur arbitraire dans le champ.
Attention aussi, le répertoire courant et le répertoire avec l'exécutable sont deux choses différentes, donc getcwd () ne vous aidera pas non plus.
Sous Windows, utilisez GetModuleFileName (), sous Linux, lisez les fichiers / dev / proc / procID / ...
la source
Juste pour empiler tardivement ici, ...
il n'y a pas de solution standard, car les langues sont indépendantes des systèmes de fichiers sous-jacents, de sorte que, comme d'autres l'ont dit, le concept d'un système de fichiers basé sur un répertoire est hors de la portée des langages c / c ++.
en plus de cela, vous ne voulez pas le répertoire de travail actuel, mais le répertoire dans lequel le programme s'exécute, qui doit tenir compte de la façon dont le programme est arrivé là où il se trouve - c'est-à-dire qu'il a été généré comme un nouveau processus via un fork, etc. Pour obtenir le répertoire dans lequel un programme s'exécute, comme les solutions l'ont démontré, vous devez obtenir ces informations des structures de contrôle de processus du système d'exploitation en question, qui est la seule autorité sur cette question. Ainsi, par définition, c'est une solution spécifique au système d'exploitation.
la source
Pour le système Windows sur la console, vous pouvez utiliser la
dir
commande system ( ). Et la console vous donne des informations sur le répertoire et etc. Lisez ladir
commande surcmd
. Mais pour les systèmes de type Unix, je ne sais pas ... Si cette commande est exécutée, lisez la commande bash.ls
n'affiche pas le répertoire ...Exemple:
la source
la source
Sur les plateformes POSIX, vous pouvez utiliser getcwd () .
Sous Windows, vous pouvez utiliser _getcwd () , comme l'utilisation de getcwd () est déconseillée.
Pour les bibliothèques standard, si Boost était suffisamment standard pour vous, j'aurais suggéré Boost :: filesystem, mais elles semblent avoir supprimé la normalisation des chemins de la proposition. Vous devrez peut-être attendre que TR2 devienne facilement disponible pour une solution entièrement standard.
la source
Pour les chemins relatifs, voici ce que j'ai fait. Je connais l'âge de cette question, je veux simplement apporter une réponse plus simple qui fonctionne dans la majorité des cas:
Disons que vous avez un chemin comme celui-ci:
Pour une raison quelconque, les exécutables Linux construits dans eclipse fonctionnent très bien avec cela. Cependant, Windows devient très confus si on lui donne un chemin comme celui-ci pour travailler!
Comme indiqué ci-dessus, il existe plusieurs façons d'obtenir le chemin actuel vers l'exécutable, mais la manière la plus simple que je trouve fonctionne dans la plupart des cas est d'ajouter ceci au FRONT de votre chemin:
L'ajout de "./" devrait vous permettre de trier! :) Ensuite, vous pouvez commencer à charger à partir du répertoire de votre choix, à condition que ce soit avec l'exécutable lui-même.
EDIT: Cela ne fonctionnera pas si vous essayez de lancer l'exécutable à partir de code :: blocks si c'est l'environnement de développement utilisé, car pour une raison quelconque, code :: blocks ne charge pas les choses correctement ...: D
EDIT2: J'ai découvert de nouvelles choses si vous spécifiez un chemin statique comme celui-ci dans votre code (en supposant que Example.data soit quelque chose que vous devez charger):
Si vous lancez ensuite votre application à partir du répertoire réel (ou dans Windows, vous créez un raccourci et définissez le répertoire de travail sur votre répertoire d'application), cela fonctionnera comme ça. Gardez cela à l'esprit lorsque vous déboguez des problèmes liés aux chemins de ressources / fichiers manquants. (Surtout dans les IDE qui définissent le mauvais répertoire de travail lors du lancement d'un exe de build à partir de l'IDE)
la source
Une solution de bibliothèque (même si je sais que cela n'a pas été demandé). Si vous utilisez Qt:
QCoreApplication::applicationDirPath()
la source
Juste mes deux cents, mais le code suivant ne fonctionne-t-il pas de manière portable en C ++ 17?
Semble fonctionner pour moi sur Linux au moins.
Sur la base de l'idée précédente, j'ai maintenant:
Avec mise en œuvre:
Et astuce d'initialisation dans
main()
:Merci @Sam Redway pour l'idée argv [0]. Et bien sûr, je comprends que C ++ 17 n'était pas là depuis de nombreuses années lorsque l'OP a posé la question.
la source
Boost Filesystem se
initial_path()
comporte comme POSIXgetcwd()
, et ne fait pas non plus ce que vous voulez, mais en ajoutantargv[0]
à l'un d'eux devrait le faire.Vous pouvez noter que le résultat n'est pas toujours joli - vous pouvez obtenir des choses comme
/foo/bar/../../baz/a.out
ou/foo/bar//baz/a.out
, mais je crois qu'il en résulte toujours un chemin valide qui nomme l'exécutable (notez que les barres obliques consécutives dans un chemin sont réduites à un).J'ai déjà écrit une solution en utilisant
envp
(le troisième argumentmain()
fonctionnait sous Linux mais ne semblait pas réalisable sous Windows, donc je recommande essentiellement la même solution que quelqu'un d'autre, mais avec l'explication supplémentaire de la raison pour laquelle elle est réellement correcte même si les résultats ne sont pas jolis.la source
Comme Minok l'a mentionné, aucune fonctionnalité de ce type n'est spécifiée dans la norme C ou la norme C ++. Ceci est considéré comme une fonctionnalité purement spécifique au système d'exploitation et il est spécifié dans la norme POSIX, par exemple.
Thorsten79 a donné une bonne suggestion, c'est la bibliothèque Boost.Filesystem. Cependant, cela peut être gênant si vous ne souhaitez pas avoir de dépendances de temps de liaison sous forme binaire pour votre programme.
Une bonne alternative que je recommanderais est la collection de bibliothèques 100% STLSoft C ++ uniquement pour les en-têtes Matthew Wilson (auteur de livres incontournables sur C ++). Il existe une façade portable PlatformSTL donne accès à une API spécifique au système: WinSTL pour Windows et UnixSTL sous Unix, il s'agit donc d'une solution portable. Tous les éléments spécifiques au système sont spécifiés avec l'utilisation de traits et de politiques, il s'agit donc d'un cadre extensible. Il y a bien sûr une bibliothèque de système de fichiers.
la source
La commande linux bash qui progname rapportera un chemin vers le programme.
Même si l'on pouvait émettre la commande which depuis votre programme et diriger la sortie vers un fichier tmp et que le programme lit ensuite ce fichier tmp, il ne vous dira pas si ce programme est celui qui s'exécute. Il vous indique uniquement où se trouve un programme portant ce nom.
Ce qui est nécessaire est d'obtenir votre numéro d'identification de processus et d'analyser le chemin d'accès au nom
Dans mon programme, je veux savoir si le programme a été exécuté à partir du répertoire bin de l'utilisateur ou d'un autre dans le chemin ou à partir de / usr / bin. / usr / bin contiendrait la version prise en charge. Mon sentiment est que sous Linux, il existe une seule solution qui est portable.
la source
Utilisez
realpath()
dansstdlib.h
comme ceci:la source
Fonctionne à partir de C ++ 11, en utilisant un système de fichiers expérimental, et C ++ 14-C ++ 17 ainsi qu'en utilisant un système de fichiers officiel.
application.h:
application.cpp:
la source
std
. Pour éviter cela, vous pouvez ajouter à la fois les espaces de nomsstd::filesystem
etstd::experimental::filesystem
un troisième espace de noms de votre choix, ou simplement utiliserusing std::filesystem::path
, si cela ne vous dérange pas d'ajouter la déclaration depath
à l'espace de noms global.