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 :

Decomposer une chaine de caractere


Sujet :

C++

  1. #1
    Membre régulier
    Inscrit en
    Mars 2008
    Messages
    296
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 296
    Points : 103
    Points
    103
    Par défaut Decomposer une chaine de caractere
    bonjour,

    j'ai une variable valeur qui contient : ON/OFF/DEF

    et je voudrais le code qui me permet de recuperer
    ON dans val1
    OFF dans val2
    DEF dans val3

    merci

  2. #2
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    Hello,

    ça m'étonnerai que quelqu'un te donne le code tout fait...
    je vais donc plutot t'orienter vers une solution


    D'abord, de quel type est ta variable valeur?

    si c'est un std::string, alors je te propose de regarder la fonction find pour trouver les indices des /.
    Ensuite, la fonction substr pourra t'aider


    si c'est un char*, tu devrai plutot poser la question dans le forum C

    bon courage!

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017

  4. #4
    Membre régulier
    Inscrit en
    Mars 2008
    Messages
    296
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 296
    Points : 103
    Points
    103
    Par défaut
    Bon pas de chance c'es un char*

    le tokenizer : j'ai rien compris
    le find je trouve pas ce que je dois mettre en parametres

    il n'y a pas un truc avec des strcpy, ou right....?

    merci

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par cortex59 Voir le message
    Bon pas de chance c'es un char*

    le tokenizer : j'ai rien compris
    Pourtant, c'est tout écrit (tu peux aussi voir ici) :
    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
     
    #include <boost/tokenizer.hpp>
    #include <string>
     
    void split( const std::string & Msg, const std::string & Separators )
    {
        // typedef pour alléger l'écriture
        typedef boost::tokenizer<boost::char_separator<char> > my_tok;
     
        // séparateur personnalisé
        boost::char_separator<char> sep( Separators.c_str() );
     
        // construire le tokenizer personnalisé
        my_tok tok( Msg, sep );
     
        // itérer la séquence de tokens
        for ( my_tok::const_iterator i = tok.begin();
              i != tok.end();
              ++i )
        {
            // afficher chaque token extrait
            std::cout << *i << '\n';
        }
    }
    // puis quelque part : 
      split("ON/OFF/DEF","/");
    Citation Envoyé par cortex59 Voir le message
    il n'y a pas un truc avec des strcpy, ou right....?

    merci
    Tutoriels?

  6. #6
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    tu peux aussi convertir ton char* en string... ensuite:

    en gros, le find il te permet de trouver l'indice du caractère que tu cherches
    si tu as:
    string maString = "bonjour";
    alors:
    maString.find('b') retourne 0 (b est à la position 0 dans "bonjour")
    maString.find('o') retourne 1
    maString.find('n') retourne 2

    mais si tu cherches le 2eme 'o'... alors tu peux faire:
    maString.find('o',3) (il va chercher un 'o' a partir du 3eme caractère... donc il ne vas pas tomber sur le premier)


    et substr c'est simple:
    string maSub = maString.substr(2,3); //maSub = "njo"... je te laisse deviner pourquoi


    la tu devrais t'en sortir...

  7. #7
    Membre régulier
    Inscrit en
    Mars 2008
    Messages
    296
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 296
    Points : 103
    Points
    103
    Par défaut
    le probleme c que je ne sais pas combien de "/" a dans ma chaine
    et que je veu mettre les champs dans des variables differentes

    merci

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    J'insiste avec mon boost
    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
     
    template<class TConteneur>
    void split( const std::string & Msg, const std::string & Separators, TConteneur&Conteneur )
    {
        // typedef pour alléger l'écriture
        typedef boost::tokenizer<boost::char_separator<char> > my_tok;
     
        // séparateur personnalisé
        boost::char_separator<char> sep( Separators.c_str() );
     
        // construire le tokenizer personnalisé
        my_tok tok( Msg, sep );
     
        // inserter : 
        std::back_insert_iterator<TConteneur> it_insertion(Conteneur);
     
        // itérer la séquence de tokens
        for ( my_tok::const_iterator i = tok.begin();
              i != tok.end();
              ++i )
        {
            // afficher chaque token extrait
           *it_insertion = *i;
           ++it_insertion;
        }
    }
     int main()
    {
    // puis quelque part : 
       std::vector<std::string> vect_str;
      split("ON/OFF/DEF/1/2/3","/",vect_str);
     
      std::copy(
         vect_str.begin(),
         vect_str.end(),
         std::ostream_iterator<std::string>(std::cout,"\n")
         );
     
        return 0;
    }

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Oui, enfin plus de quinze lignes de code pour une opération aussi basique que la tokenization d'une chaine avec des choses comme boost::tokenizer<boost::char_separator<char> >, std::back_insert_iterator<TConteneur> + boucles d'itérateurs... ça ne coule pas de source quand même.

    Heureusement boost::split et boost::split_regex est bien plus simple d'emploi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    std::vector<std::string> result;
    std::string s = "ON/OFF/DEL";
    boost::split(s, result, is_any_of("/"));
     
    std::vector<std::string> result2;
    std::string s2 = "ON////OFF//DEL";
    boost::split_regex(s2, result2, boost::regex("/+"));
    Edit : En c++ standard, il faut se palucher la tokenization à la main à base de string::find + string::substr.

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par cortex59 Voir le message
    Bon pas de chance c'es un char*

    le tokenizer : j'ai rien compris
    le find je trouve pas ce que je dois mettre en parametres

    il n'y a pas un truc avec des strcpy, ou right....?

    merci
    Comma ça, très vite
    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
    void foo(char *text)
    {
    	std::vector<char *> pf;
     
    	char *p1=text;
    	char *pend=p1+strlen(text);
    	while (p1<=pend)
    	{
    		pf.push_back(p1);
    		//find next tab
    		while (*p1!='/' && *p1!='\0')
    			++p1;
    		*p1='\0';
    		//move beyond next tab
    		++p1;
    	}
     
    	//utiliser pf
    }
    A toi de parfaire pour que se soit plus "propre" et en utilisant des std::string.

    Ou alors tu fais comme les autres te le proposent, tu utilises un canon pour tuer une mouche...

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    soit avec substr, mais personne n'a parlé de getline avant de sortir boost?

    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
     
    #include <string>
    #include <sstream>
    #include <iostream>
     
    int main()
    {
        std::string v = "a/b/c";
        std::istringstream iss( v );
     
        std::string v1;
        std::getline( iss, v1, '/' );
     
        std::string v2;
        std::getline( iss, v2, '/' );
     
        std::string v3;
        std::getline( iss, v3, '/' );
     
        std::cout << v1 << " " << v2 << " " << v3 << std::endl;
     
        return 0;
    }

  12. #12
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    A mon tour d'insister.
    Sans boost, la solution la plus élégante passe par string::find et string::substr
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void foo(const std::string& s, char token, std::vector<std::string>& result)
    {
    	std::string::size_type first = 0, last;
    	while (first != std::string::npos)
    	{
    		last = s.find_first_of(token, first);
    		result.push_back(s.substr(first, last - first));
    		first = s.find_first_not_of(token, last);
    	}
    }
    Camboui, ton code m'a l'air un peu violent non ? La chaine de départ est complètement bousillée en sortant de la fonction.

  13. #13
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    C'était pas précisé dans le cahier des charges, alors j'ose
    Et puis je savais bien que tous les autres répondants allaient proposer un code banal, quelconque, académique. Alors j'ai proposé un code qui n'est pas une solution toute faite, mais qui demande réflexion

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

Discussions similaires

  1. decomposer une chaine de caractere
    Par cortex59 dans le forum VB.NET
    Réponses: 2
    Dernier message: 22/05/2008, 19h48
  2. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  3. Extraire un nom d'une chaine de caractere
    Par iamspacy dans le forum Linux
    Réponses: 4
    Dernier message: 03/05/2004, 21h34
  4. Réponses: 2
    Dernier message: 30/03/2004, 11h31
  5. Controler une chaine de caracteres ou d'entiers?
    Par Le druide dans le forum C
    Réponses: 6
    Dernier message: 25/09/2003, 08h48

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