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

SL & STL C++ Discussion :

switch de string


Sujet :

SL & STL C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 10
    Points : 11
    Points
    11
    Par défaut switch de string
    Salut,

    j'ai lu un peu partout qu'il est impossible de faire un switch de string. Je voudrai poster une solution pour contourner le problème. Voici le code (compile sous g++ 3.3):

    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
     
    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
     
    int main(int argc, char *argv[]){
    /*************************** 
    * Petit parseur decommande
    * G. Marcou
    ***************************/
        typedef map<string,int> StrInt;
        StrInt coms;
        string com;//Inutile, pour montrer que c'est bien une variable string
     
    // Definition de la map
        coms["-to"]=0;
        coms["-ti"]=1;
     
    //Boucle sur les options
        while ((argc > 1) && (argv[1][0] == '-')) {
    // Trouver l'entree de la map qui correspond au string
            com=argv[1];//On peut utiliser argv directement
    	map<string,int>::const_iterator i = coms.find( com );
    // Blinder le programme
    	if(i == coms.end()){
    	    test(argv,argc);
    	    cout << "Unknown parameter" << endl;
    	    return(1);
    	};
    // Le fameux switch... 
    	switch (i->second){
                case 0://-to
    		--argc;
    		++argv;
    		cout << "toto" <<endl;
    		break;
                case 1://-ti
    		--argc;
    		++argv;
    		cout << "titi" << endl;
    		break;
    	};
        };
        return(0);
    }
    C'est une solution que je n'ai pas rencontrée auparavant. J'aimerai savoir si elle pose en soi un problème qui fait qu'on lui préfère des if imbriqués (solution le plus souvent proposée, je crois).

    Ciao!

  2. #2
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Salut,

    c'est bien de cette FAQ que j'ai dérivé mon exemple. Mais la solution de la FAQ est différente dans la mesure où elle consiste à appeler des fonctions pour chaque couple clef/valeur de la map. En dehors du fait qu'il y a donc un appel de fonction pour chaque chaine traitée, il ne me semble pas possible de reproduire l'omission du 'break' dans le switch. En somme que deux ou plusieurs chaines (ici deux ou plus case du switch) partagent une partie des instructions.

    Pour en revenir à ma question, un de mes collègue m'a expliqué que la solution que j'ai proposé produit un code très "sale", contenant beaucoup trop d'instructions pour le résultat souhaité. Au contraire, un ensemble de if imbriqués reste quasiment inchangé au cours de la compilation...

    De mon point de vue tout commentaire est le bienvenue pour y voir plus clair...

    Ciao!

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    l ne me semble pas possible de reproduire l'omission du 'break' dans le switch
    ben il suffit d'associer 2 fois la même fonction à 2 string différentes.

    La map plus sale que des if...else imbriqués... Ca produit peut être plus d'instructions, mais ça demande moins de lignes de code (sauf pour de tous petits exemples) et c'est bien ces lignes de code C++ qui comptent, et pas le code asm généré derrière; surtout que la map est plus rapide que des if...else imbriqués.
    Un nombre élevé de if...else imbriqué est plutôt considéré comme du mauvais design => comme du code sale, à moins d'avoir 2 ou 3 strings à tester. Car certes coder "le moteur" est un peu plus long, mais par la suite c'est bien plus souple et élégant, alors qu'inversement les imbrications de if...else rendent le code de plus en plus obscure.
    Si c'est pour traiter les paramètres en ligne de commande, inspire toi plutot de choses déjà faites, comme boost::program_options.
    http://www.boost.org/doc/html/program_options.html
    ou encore:
    http://www.codeproject.com/cpp/#Command+line+processing

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Merci pour ces précisions. Si j'ai bien compris, l'utilisation de la commande switch doit etre privilégiée quand elle est accessible. Dans l'exemple que j'ai fourni auparavant, l'utilisation de la map n'induit pas ou très peu de déterioration des performances vis-à-vis de if...else imbriqués. En revanche, le code gagne en clarté et concision.

    Pour la question du break manquant, je pensais à une situation de ce type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    swith(opt){
       case 0:
          cout << "Si j'ai 0..."
       case 1:
          cout << "J'ai 1";
          break;
       default:
          cout << "defaut";
          break;
    }; cout << endl;
    Quand , le programme exécute un code spécifique à 1, mais quand le code spécifique à 0 ET à 1 est exécuté.

    C'est vrai que c'est lors de la conception d'une interface utilisateur que j'en suis venu à me poser ces questions. Je ne connaissais pas boost. Je vais jeter un coup d'oeil. Mais ce type de questions peut avoir des applications par exemple dans le design de modules pour lire de multiples formats en bio/cheminfo. On peut trouver un intéret à cette syntaxe également dans l'alignement de séquences... Un exemple concret serait l'ajout d' atomes d'hydrogène aux différents type d'acides aminés définis par leur code 1 lettre ou 3 lettre ou leur nom entier. Ces données provenant généralement de la lecture d'un fichier, elles se trouvent etre habituellement stockées dans un tableau de char ou une variable string.

    Bon ben j'ai appris des trucs aujourd'hui!

    Ciao!

  6. #6
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    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 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Hello
    Citation Envoyé par Marcou
    a- Si j'ai bien compris, l'utilisation de la commande switch doit etre privilégiée quand elle est accessible.
    b- Dans l'exemple que j'ai fourni auparavant, l'utilisation de la map n'induit pas ou très peu de déterioration des performances vis-à-vis de if...else imbriqués.
    c- En revanche, le code gagne en clarté et concision.
    a- C'est plutôt le contraire. switch n'est pas évolutif et va un peu à l'encontre du principe qu'un programme devrait être ouvert aux évolutions et fermé aux modifications.

    b- euh ... c'est plutôt les if qui devraient être pénalisants sur un nombre non ridicule de cas différents. Si la liste de cas n'est pas appelée à évoluer, on peut accélérer le traitement avec un vecteur trié et std::binary_search -- enfin, inutile d'optimiser ce genre de trucs tant que l'intérêt n'a pas été prouvé.

    c- Tout à fait, les map améliorent tout ça. Ce qui induit une meilleure maintance.

    Enfin, si il faut faire des parseurs, il y a d'autres techniques plus adaptées.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Salut,

    je ne comprend pas bien en quoi une instruction switch rend le code plus difficile à faire évoluer?

    Pour le point b, une série de if...else est inefficace parce qu'elle contraint le code à faire ses tests séquenciellement. Sur quelles bases se font les recherches dans une map ou une instruction switch?

    Ciao!

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    La map est triée en interne. Ca augmente le coup d'une insersion, mais la recherche est bien plus rapide.

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Sur quelles bases se font les recherches dans une map ou une instruction switch?
    Habituellement la map est organisée en arbre binaire, d'où une recherche en temps logarithmique. Pour le switch, le compilo construit une table de saut, donc la recherche est en temps constant. Mais bon, cela a rarement de l'importance.

  10. #10
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    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 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par Marcou
    je ne comprends pas bien en quoi une instruction switch rend le code plus difficile à faire évoluer?
    Je vais faire parler d'autres que moi, et voici un résultat vite cherché et vite trouvé sur google avec <<"open close principle" switch>>
    http://www.eventhelix.com/RealtimeMa..._principle.htm

    Rajouter de nouveaux cas n'implique pas de modifier le code. Juste de rajouter "ailleurs" des choses qui par addition font évoluer l'ensemble.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Merci pour tout.

    Ciao!

Discussions similaires

  1. Switch sur String
    Par Sylar44 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 29/03/2015, 18h18
  2. Switch avec String
    Par Aymenkn dans le forum Langage
    Réponses: 2
    Dernier message: 05/01/2015, 14h54
  3. switch char/string imbriqués C++
    Par senvedgi dans le forum C++
    Réponses: 3
    Dernier message: 28/05/2011, 21h31
  4. Contourner un switch de strings
    Par magnus2229 dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 29/04/2011, 10h21

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