IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Paramètres de ligne de commande facultatifs


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Points : 185
    Points
    185
    Par défaut Paramètres de ligne de commande facultatifs
    Bonjour à tous,

    je souhaite écrire en C++ un programme qui peut prendre un certain nombre de paramètres en ligne de commande, mais ceux-ci doivent être facultatifs (une valeur par défaut est donnée dans le programme pour les paramètres non renseignés).

    Les paramètres de mon main seront donc très classiquement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int main(int n, char* params[])
    Le problème, c'est que les paramètres doivent être identifiables indépendamment de leur position puisque ils sont facultatifs.

    Autrement dit, on doit pouvoir lancer le programme comme ça par exemple:
    >ProgramName.exe -paramName1=toto -paramName4=titi -paramName3=tata

    Et donc, je ne sais pas comment faire pour récuperer la valeur des paramètres, c'est-à-dire "toto", "tata", ...

    Je saurais le faire avec des Regex, en parsant les params[n], mais je ne peux pas utiliser Boost :/
    Les seules bibliothèques que j'ai à ma disposition sont la STL et l'API Win32.

    Merci d'avance à tous ceux qui pourront m'aider !

  2. #2
    Membre habitué Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Points : 185
    Points
    185
    Par défaut
    Rien de bien difficile il me semble :

    Parcours ta chaine, cherches le caractere '-' dans la chaine, puis tous les caracteres suivants sont stockés dans une chaine "nomoption" jusqu'a tomber sur "=" puis tous les caracteres suivants sont stockés dans une chaine "valeuroption" jusqu'a tomber sur un caractere ' ' (espace)

    En C ca se fait facilement, et c'est encore plus simple en C++ avec la classe std::string

    EDIT : Alternativement, tu peux aussi d'abord chercher les index des 3 caracteres separateurs, et faire les 2 copies d'un coup (au lieu de copier caractere par caractere)...Je suis pas trop en etat de reflechir a quelle solution est la plus efficace

  3. #3
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Points : 661
    Points
    661
    Par défaut
    ca devrait faire l'affaire pour autant que tu supprimes les petites reference MFC si il y en a.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    char szName[MAX_PATH];   	
    GetModuleFileName(AfxGetInstanceHandle(),szName,MAX_PATH);
     
    CArray<CString ,const char *> argv; // attention il faut mettre #include <afxtempl.h> dans stdafx.h
     
    char *szArg=strtok(m_lpCmdLine," ");	
     
    argv.Add(szName); // argv[0]=path de l'application.
    if(szArg) 
    {
        do
        {
            argv.Add(szArg);
        }
        while(szArg=strtok(NULL," "));
    }
     
    int argc=argv.GetSize();
    for(int i=0;i<argc;i++)
    {
        TRACE("I\t Argv[%d]=%s\r\n",i,argv[i]);
    }
    avec


  4. #4
    Membre habitué
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Points : 186
    Points
    186
    Par défaut
    ça se fait très facilement avec boost::program_options. Je l'utilise très fréquemment en m'aidant parfois de boost::tokenizer...

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    Citation Envoyé par superspag
    ça se fait très facilement avec boost::program_options. Je l'utilise très fréquemment en m'aidant parfois de boost::tokenizer...
    tu pourrais poster un petit exemple ?

  6. #6
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Points : 68
    Points
    68
    Par défaut
    Sinon, tu peux utiliser getopt, fonction qui permet de récupérer les options de la ligne de commande.

    EDIT : mais cette fonction ne fait pas partie du standard C++, mais du standard POSIX. Je crois qu'on peut en trouver une version c++.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Territoire de Belfort (Franche Comté)

    Informations forums :
    Inscription : Mars 2006
    Messages : 80
    Points : 77
    Points
    77
    Par défaut
    Citation Envoyé par superspag
    ça se fait très facilement avec boost::program_options. Je l'utilise très fréquemment en m'aidant parfois de boost::tokenizer...
    Je pense que Lawyer666 avait préciser qu'il ne peut pas utiliser boost

  8. #8
    Membre habitué
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Points : 186
    Points
    186
    Par défaut
    Citation Envoyé par stranger
    Je pense que Lawyer666 avait préciser qu'il ne peut pas utiliser boost
    A oui en effet, j'ai vu ça aprés coup... autant pour moi

    Citation Envoyé par epsilon68
    tu pourrais poster un petit exemple ?
    Oui bien sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    #include <string>
    #include <iostream>
    #include <boost/program_options.hpp>
     
    int main(int argc, char* argv[])
    {
      // Déclaration des options 'Génériques' :
      namespace po = boost::program_options ;
      po::options_description generic("Generic options") ;
      generic.add_options()
        ("help,h"     , "produce a help message"    )
        ("version,v"  , "output the version number" ) 
        ;
      // Déclaration d'autres options :
      std::string    thePath;
      unsigned short theNumber;
      po::options_description other("Other options");
      other.add_options()
        ("path,p"   , po::value<std::string>(&thePath)               
                    , "set path"    )
        ("number,n" , po::value<unsigned short>(&theNumber)
                    , "set number"  )
        ;
      // Déclaration d'une instance de options_description qui regroupe l'ensemble des options :
      po::options_description cmdLineOpt("Allowed options") ;
      cmdLineOpt.add(generic).add(other);
     
      // Parsing :
      po::variables_map vm ;
      po::store(po::parse_command_line(argc, argv, cmdLineOpt), vm) ;
      po::notify(vm) ;  
     
      std::string appVersionId = "v0.1";
     
      if( vm.count("version") )  { 
        std::cout << "App Version " << appVersionId << std::endl ; 
        return 0 ;  
      }
     
      if( vm.count("help") )  { 
        std::cout << cmdLineOpt << std::endl ; 
        return 0 ;  
      }
     
      if( vm.count("path") )  { 
        std::cout << "path = " << thePath << std::endl ; 
      }
     
      if( vm.count("number") )  { 
        std::cout << "number = " << theNumber << std::endl ; 
      }
    }
    si on demande d'afficher l'aide, ça donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Allowed options:
     
    Generic options:
      -h [ --help ]         produce a help message
      -v [ --version ]      output the version number
     
    Other options:
      -p [ --path ] arg     set path
      -n [ --number ] arg   set number
    C'est plutôt pratique je trouve

  9. #9
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    Citation Envoyé par epsilon68
    tu pourrais poster un petit exemple ?
    Dis tout de suite que l'exemple que je t'avais donné ne t'avais pas plu
    http://www.developpez.net/forums/sho...=1#post1588859







    Sinon, sans sortir des trucs qui nous facilitent la vie, une simple boucle suffit. C'est un peu le b à ba.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for (int i=1 ; i<argc ; ++i) {
        if      (! strcmp("-h", argv[i]) ) { 
           return usage();
        else if (! strcmp("-o", argv[i]) ) {
            setParam_o(argv[++i]);
       ....
    C'est sûr que cela va demander un peu d'huile de coude pour réinventer la reconnaissance de "-p=VAL", "-p VAL", "--param=VAL", "--list=1,2,3", ...

    std::string::find ou std::strchr seront tes amis. Surtout std::string::find

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par superspag
    ça se fait très facilement avec boost::program_options. Je l'utilise très fréquemment en m'aidant parfois de boost::tokenizer...
    +1
    La doc est un peu obscure, mais ça se fait. Mais je n'ai pas encore fait de tuto dessus...

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    Citation Envoyé par Luc Hermitte
    Dis tout de suite que l'exemple que je t'avais donné ne t'avais pas plu
    http://www.developpez.net/forums/sho...=1#post1588859
    il faut etre positif: c'est toujours tres interessant de comparer et de voir comment plusieurs personnes font....

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/03/2010, 15h25
  2. Réponses: 4
    Dernier message: 05/11/2009, 11h42
  3. Réponses: 3
    Dernier message: 17/04/2008, 15h01
  4. Réponses: 0
    Dernier message: 20/11/2007, 11h35
  5. Réponses: 9
    Dernier message: 06/07/2005, 18h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo