2009-04-10 10 views
4

Hey, j'ai écrit un programme (une sorte de chose de type e-Book) et il charge des fichiers texte à partir d'un dossier dans le dossier dans lequel se trouve l'exécutable. Cela me pose un petit problème car si je lance le programme depuis un autre répertoire avec la commande "./folder/folder/program" par exemple, mon programme ne trouvera pas le texte, car le répertoire de travail n'est pas correct. Je ne peux pas avoir un répertoire absolu parce que je voudrais que le programme soit portable. Est-il possible d'obtenir le répertoire précis que l'exécutable exécute même s'il a été exécuté à partir d'un répertoire différent. J'ai entendu que l'on pourrait combiner argc [0] et getcwd() mais argc est tronqué quand il y a un espace dans le répertoire, (je pense?) Donc je voudrais éviter cela si possible.Répertoire du programme en cours sous Linux?

Je suis sous Linux avec g ++, Thanx à l'avance

+1

argv est le vecteur d'argument (tableau de pointeurs vers des chaînes). argv [0] n'est pas tronqué par des espaces; argv [0] est choisi par le programme qui lance le programme et ne porte pas nécessairement de relation avec le chemin du programme. N'ajoutez pas getcwd() si argv [0] commence '/'. –

+0

Avez-vous accès à la bibliothèque boost? –

+0

Attendez une seconde. Avez-vous besoin d'un "chemin exécutable" ou d'un "répertoire exécutable par l'exécutable"? –

Répondre

8

EDIT - n'utilisez pas getcwd(), c'est juste là où l'utilisateur n'est pas où est l'exécutable.

Voir here for details.

Sur linux/proc/<pid>/exe ou/proc/self/exe doit être un lien symbolique vers votre exécutable. Comme d'autres, je pense que la question la plus importante est "pourquoi avez-vous besoin de cela?" Ce n'est pas vraiment une forme UNIX pour utiliser le chemin exécutable pour trouver des fichiers auxiliaires. Au lieu de cela, vous utilisez une variable d'environnement ou un emplacement par défaut, ou suivez l'une des autres conventions pour trouver l'emplacement des fichiers auxiliaires (par exemple, ~ /. <myapp> rc).

+0

"... ce n'est pas vraiment une forme UNIX ..." De quelle forme s'agit-il? Je pensais que ce n'était pas vraiment ANY_OS_FORM. –

+0

Comme plinth recommande: ajouter un fichier de configuration/répertoire pour l'utilisateur/système et rechercher des chemins complets. A titre d'exemple, les fichiers de configuration globaux devraient aller dans/etc, alors que les fichiers de configuration utilisateur sont généralement dans ~ /. rc pour un fichier ou sous un ~ /. répertoire. –

+0

Mykola - c'est plus sous forme Macintosh/Windows de 1980. Mon application vit dans un dossier et ses fichiers de support sont liés à celle-ci. Pour trouver les fichiers de support, on trouve d'abord où se trouve l'application. – plinth

0

Vous pouvez obtenir le chemin du programme en cours d'exécution en lisant la ligne de commande. Sous Linux, vous pouvez obtenir la ligne de commande en lisant le dossier/proc sous la forme/proc/PID/CommandLine

2

Lorsque vous ajoutez un livre à votre bibliothèque, vous pouvez mémoriser son chemin absolu.
Ce n'est pas un problème quand votre programme compte sur le fait qu'il sera lancé à partir du répertoire de travail et non d'un autre répertoire. C'est pourquoi il existe toutes sortes de "liens" avec le paramètre "dir".

Vous n'avez pas à gérer de telles situations comme vous le souhaitez. Vérifiez simplement si tous les fichiers nécessaires et la structure des répertoires sont en place et consignez une erreur avec les instructions si elles ne le sont pas.

Ou chaque fois que votre programme démarre et ne trouve pas les fichiers nécessaires, le programme peut demander de pointer le chemin vers la bibliothèque de livres.

Je ne vois toujours pas la raison de connaître votre nom de répertoire actuel.

#include <boost/filesystem/convenience.hpp> 

#include <iostream> 
#include <ostream> 

int main(int argc, char** argv) 
{ 
    boost::filesystem::path argvPath(argv[0]); 
    boost::filesystem::path executablePath(argvPath.parent_path()); 
    boost::filesystem::path runPath(boost::filesystem::initial_path()); 

    std::cout << executablePath << std::endl; 
    std::cout << runPath << std::endl; 
    return 0; 
} 
0

argv[0] n'est pas tronqué lorsqu'il y a des espaces. Cependant, il aura seulement le nom du programme et pas le chemin quand un programme est exécuté à partir d'un répertoire répertorié dans la variable d'environnement PATH.

Dans tous les cas, ce que vous essayez de faire ici n'est pas une bonne conception pour un programme Unix/Linux. Les fichiers de données ne sont pas stockés dans le même répertoire que les fichiers de programme, car cela rend difficile l'application de stratégies de sécurité appropriées.

La meilleure façon d'obtenir ce que vous voulez est d'utiliser un script shell pour lancer le programme. Ceci est très similaire à la façon dont Firefox se lance sur les systèmes Linux. Le shell place le nom du script dans $0 et cette variable aura toujours un chemin.Ensuite, vous pouvez utiliser une variable d'environnement ou l'argument en ligne de commande pour donner à votre programme l'emplacement des fichiers de données, comme ceci:

dir=`dirname "$0"` 
cd "$dir/../data/" 
"$dir/real-program" 

Et j'organiser votre programme afin qu'il soit des fichiers sont un peu comme ceci:

Argc est le nombre d'arguments;
install-dir/bin/program 
install-dir/bin/real-program 
install-dir/etc/config 
install-dir/data/book-file.mobi 
Questions connexes