Chemin absolu de l'application

Résolu
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 19 févr. 2010 à 14:00
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 23 févr. 2010 à 11:08
bonjour,

J'ai un problème sur l'ouverture d'un fichier :
j'ai un attribut de ma classe m_FileName = "data/test.txt"
Dans une méthode, je fais un myFile.Open(m_FileName.c_str(), ios::out | ios::trunc)
et ça ne marche pas. Apparemment, il y a un soucis sur le chemin du fichier, puisque quand je renomme le fichier en "test.txt" tout court, tout va bien...
Donc, existe-t-il un moyen de récupérer le chemin absolu de l'application de façon à le rajouter devant le nom de fichier ?

Merci d'avance


Simon

17 réponses

Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 févr. 2010 à 14:58
Oui, en effet, j'avais pas fait attention que tu étais sous linux...
Je ne m'y connais pas trop pour Linux mais il semblerait qu'il n'y ai pas d'équivalent direct: (Il faut utiliser argv[0])
http://www.gamedev.net/community/forums/topic.asp?topic_id=459511
A+


____________________________________________________________________________
Logiciel en traitement de l'image gratuit et open source.
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
19 févr. 2010 à 16:22
Au temps pour moi, je n'avais pas fait attention !
Je regarde peu souvent cette partie de la page (elle n'est pas souvent respectée par ceux qui postent, j'ai appris à ne plus m'y fier).
Pour Boost, ton prof devrait en avoir une copie, tout simplement. Mais c'est un autre débat.

Pour répondre à ta question, le plus simple, et le plus rapide reste ceci:
#include 
#include <dirent.h>

int main()
{
  char buff[256] = {0};

  getcwd(buff, 256);

  std::cout << buff << std::endl;

  return 0;
}




_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
3
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
22 févr. 2010 à 19:20
Pour Windows, mieux vaut mettre un ifdef et utiliser GetModuleFileName !

Désolé, j'ai attendu lundi pour avoir quelques OS sous la main.

La norme :
The value of argc shall be nonnegative. argv[argc] shall be a null pointer.
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-de?ned values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.
The parameters argc and argv and the strings pointed to by the argv array shall be modi?able by the program, and retain their last-stored values between program startup and program termination.


Donc si argc <= 0, alors argv[0], n'est pas défini. Et "program name" ne veut pas dire grand chose...

Mais le fait est que les quelques unices que j'ai essayé semble relativement cohérent les uns par rapport aux autres !

Reste juste le problème du PATH :

prompt>cat test.c
#include <stdio.h>

int main(int argc, char** argv)
{
  puts(argv[0]);
  return 0;
}
prompt>mkdir sub
prompt>gcc test.c -o sub/test.exe
prompt>sub/test.exe
sub/test.exe
prompt>export PATH=sub:$PATH
prompt>test.exe
test.exe
prompt>


Le programme lancé trouve test.exe dans argv[0], pourtant getcwd/test.exe n'existe pas, le fichier étant dans getcwd/sub.

Il faut donc prendre en compte PATH en traitant les chemins dans l'ordre, et utiliser getcwd quand on tombe sur ".". Sachant qu'on peut tomber sur ce genre de truc : PATH=./sub., ou encore PATH=../dir/sub.

Bref, il doit y avoir moyen de s'en sortir, mais faut bien envisager tous les cas...
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
22 févr. 2010 à 20:48
@rt15: Très bonne analyse, très rigoureuse :) Un petit détail tout de même: argc ne peut être < 1. Donc argv[0] existe toujours.
Si en crois les systèmes qui respectent la norme ANSI, argc > 0:
http://notabug.com/2002/coherent/man/argc.html

De plus, d'après Kernigan:
By convention, argc is greater than zero; the first s argument (in argv[0]) is the command name itself.

Source: http://www.lysator.liu.se/c/bwk-tutor.html

Ceci devrait faire ton bonheur (à part pour le problème du PATH):
#include 
#include <cstring>
#include <cstdlib>
#include <libgen.h>

int main(int, char** argv)
{
  std::string path(argv[0]);

  char* tmpCpy = strdup(path.c_str());
  std::cout << "Dirname of " << path << " => " << dirname(tmpCpy) << std::endl;
  free(tmpCpy);

  return 0;
}


(La copie est malheureusement nécessaire, vu que dirname modifie la chaîne. Une fonction à l'aide de substring serait préférable).
A noter tout de même que si le binaire est dans le path, on peut faire un which dessus ou un locate. Et le cas que présente simonpelloquin ne devrait pas poser ce problème.

La bonne manière de faire, reste d'avoir un fichier de conf généralement dans ~/.nom_du_prog, qui contient de façon sure, ce genre d'information.

Pour windows, en revanche, je ne sais pas.
_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
19 févr. 2010 à 14:22
Salut

C'est la fonction GetModuleFileName()

A+


____________________________________________________________________________
Logiciel en traitement de l'image gratuit et open source.
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 14:44
merci pour ta réponse et ta réactivité !

euh... je suppose que je dois ajouter un "include" ?
il semble que ce soit pour windows... et je suis sous linux
une autre idée ?


Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 15:11
ok, merki, je vais fouiller

Simon
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
19 févr. 2010 à 15:48
Si j'avais sur que c'était sous Unix, je t'aurais répondu :)

Alors, tu as: Boost::FileSystem: http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/index.htm
Ou alors tu regardes dans unistd.h et dirent.h et tu va trouver tout plein de choses intéressantes, comme par exemple: getcwd: http://linux.die.net/man/3/getcwd

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 16:13
eh eh, c'était marqué dans le type du forum :
Accueil > Forum > C++ & C++ .NET > Linux > Fichier & Disque > chemin absolu de l'application
Merci CptPingu, je prends note pour la prochaine fois. Malheureusement, pour ce projet, nous avons pris la décision de ne pas utiliser boost. On doit envoyer les sources au prof et comme je n'ai pas trouvé comment ne pas lui envoyer la myriade de fichiers de cette bibliothèque (ça pourrait le saouler) ...

Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 19:03
NICKEL !!!

merci beaucoup !

Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 19:16
question subsidiaire : (comme tu m'as l'air assez calé !)

connais-tu une fonction équivalente au ExtractFilePath() de Delphi ? (qui retourne la partie répertoire d'un nom de fichier)

Après je t'embete plus (c'est le week end, quand même)

Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
19 févr. 2010 à 19:20
parce que si je lance mon prog par bin/monprog et bien le chemin ne tient pas compte du bin/
apparemment, getcwd retourne le répertoire de lancement de l'appli et non là ou elle se trouve...

Simon
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
20 févr. 2010 à 13:28
Absolument. getcwd récupère le chemin courant.
Pour avoir le nom et l'emplacement de l'exécutable, il faut se servir de argv[0].
Pour "ExtractFilePath", il suffit de faire un substring entre 0 et lastIndexOf('/'); (Voir classe String).
Ou alors regarde du côté de "dirname" et "basename".

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
20 févr. 2010 à 13:30
Salut,

connais-tu une fonction équivalente au ExtractFilePath()

Même si une fonction standard est souvent à privilégier pour gérer les cas tordus, cette fonction là n'est pas trop dur à recoder.

Concernant le chemin de l'exe et non le dossier courant, tu peux faire un readlink de /proc/self/exe. Mais ça ne fonctionnera que sous Linux.
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
20 févr. 2010 à 13:35
Post croisé avec CptPingu...
argv[0] est plus portable mais plus risqué car il peut contenir un peu n'importe quoi et surtout juste le nom de l'exécutable sans le chemin. Déduire ensuite le chemin complet avec le PATH ou un which est aussi hasardeux...
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
21 févr. 2010 à 12:59
Merci beaucoup pour vos réponses pleines de bon sens.

Effectivement, la fonction extractfilepath n'a pas l'air trop dur à recoder, mais si on peut éviter de "réinventer la roue", mieux vaut ne pas s'en priver...

@rt15 : Pourquoi est-ce hasardeux ? Apparemment, le argv[0] contient bien le nom de l'appli si je l'appelle directement dans son répertoire, et présente bien le chemin complet si je l'appelle depuis "home" par exemple. Il me semble qu'en combinant le getcwd et un "ExtractFilePath(argv[0])", j'arrive bien à ce que je recherche. As-tu un exemple pour lequel ça peut planter ? (humm, sous windows peut être ? )

Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
23 févr. 2010 à 11:08
waouh !
Merci beaucoup !

Simon
0
Rejoignez-nous