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 :

transformer un vecteur<string> en une simple string


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Par défaut transformer un vecteur<string> en une simple string
    bonjour à tous,

    Existe t'il un moyen de transformer un vecteur en string ? je m'explique j'ai créer un vecteur contenant chaque element d'une phrase via une fonction split (merci gldivers) , maintenant je tente de créer une fonction qui puisse me selectionner des elements precis de ce vecteur (exemple du 1er au 3eme element) le probleme c'est que pour retourner c'est 3 elements il faut que je les stock dans un string, j'espere que je suis compréhensible

    voici ma fonction qui est censé me retourner des elements precis d'un vecteur:

    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
     
    std::string lrange(const vector<string> &tab, unsigned int begin, unsigned int end)
    {
    	string *src;
    	src = new string[tab.size()];
     
        for (unsigned int i = 0; i < tab.size(); ++i)
        {
    		for (;begin < end; ++begin)
    		{
    			src[begin] = tab[begin];
    		}
    	}
    	return src;
    }
    la seul methode que j'ai trouvé est en utilisant new , dans ce code l'erreur ce situe sur la valeur retourner 'src', le compilateur me dit que je converti un std::string en un non-scalar std::string.
    En fait ma seule et véritable question est dans le titre :p

  2. #2
    Membre chevronné
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Par défaut
    Bah c'est normal qu'il rale, ta fonction est déclarée pour retourner une string alors que toi tu retourne un pointeur.

    Et non tu n'es pas très compréhensible, ce que tu veux faire c'est juste renvoyer un "tableau" contenant seulement certains des éléments de ton vector? et dans ce cas la, autant garder un vector aussi.
    Ou alors c'est retourner une string (donc une seule chaine de caractère), avec les différents bouts accolés les uns aux autres?
    Dans ce cas la pas besoin de new ni de pointeur...

    Après c'est pareil ta boucle semble très douteuse...

  3. #3
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Et pourquoi ne pas faire un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    std::string lrange(const vector<string> &tab, unsigned int begin, unsigned int end)
    {
    	string src;
     
        for (unsigned int i = 0; i < tab.size(); ++i)
        {
    		for (;begin < end; ++begin)
    		{
    			src += tab[begin];
    		}
    	}
    	return src;
    }

  4. #4
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Par défaut
    merci a vous deux,
    je vais tenter d'être plus claire j'ai une ligne de ce type:

    configuration4 exemple blabla test crayon sardine papier
    cette ligne je la découpe puis je stock chaque element dans un vecteur,
    dans ce vecteur il se peut que je n'ai besoin que des 3 derniers elements (exemple) d'ou la fonction lrange qui est censé me retourner ces 3 elements, mais il ne me semble pas possible de retourner 3 elements d'un vecteur sans les avoir stocké avant dans un string ... je peux me tromper c'est pour cela que je solicite votre aide, en ce qui concerne la boucle douteuse je ne sais pas si elle fonctionne car je n'ai pas pu tester la fonction lrange du fait que le compilateur grognai après mon sale boulot ...

  5. #5
    Membre chevronné
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Par défaut
    Rien ne t'empêche de retourner un deuxième vector avec uniquement les éléments que tu veux garder...

  6. #6
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Par défaut
    ca me semble être une bonne idée et c'est ce que je vais faire, par contre es-ce que je dois mettre le sujet en résolu ? parceque la question traitée dans le sujet ne l'ai pas.
    En tout cas merci

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Une bonne habitude à prendre est celle qui consiste à ne passer à une fonction que... ce dont elle a réellement besoin.

    Par exemple, une fonction qui voudrait recréer une chaine de caractères "unique" au départ d'une sélection d'éléments issus d'une collection n'a, a priori, besoin que de deux choses: les bornes représentant l'élément de départ et incluant le dernier élément à prendre en compte (donc, s'arrêtant "juste après" le dernier élément à pendre en compte )

    Le problème auquel tu pourrais en effet être confronté n'est pas forcément évident de prime abord:

    Si tu dis explicitement à ta fonction qu'elle doit s'attendre à recevoir un std::vector<std:: string>, et que tu applique la logique adéquate, cela va très bien se passer... tant que tu te retrouvera à vouloir, effectivement travailler avec un std::vector<std:: string>

    Si, pour une raison ou une autre, tu viens à te retrouver non plus avec un vecteur de chaines de caractères, mais bien avec, par exemple, une liste de chaines de caractères (std::list<std:: string> ), ta fonction ne fonctionnera purement et simplement plus, et tu te retrouveras face à la nécessité soit de... remplir un std::vector<std::string> sur base de ta liste, soit à devoir au mieux copier la fonction (qui fera pourtant exactement la même chose), au pire, la modifier en conséquence, en violation flagrante du principe qui demande qu'un code soit ouvert aux évolutions mais fermés aux modifications.

    Nous abordons là un aspect déjà un peu avancé de C++, mais c'est décidément un langage génial, et il serait bête de ne pas profiter de toutes ses possibilités

    En effet, C++ permet l'utilisation du paradigme dit "générique" qui te permet (pour faire simple) de réfléchir en des termes proches de:
    je ne sais pas quel type de donnée je vais manipuler, mais je sais comment je vais les utiliser"
    De plus, C++ présente un concept nommé "itérateur"qui permet de "voyager" entre différents éléments lorsque tu dois les manipuler de manière... itérative.

    On pourrait donc suivre un raisonnement proche de:
    Je ne sais pas d'où viendront les données, mais je sais que j'aurai deux bornes à ma disposition (une sur le premier élément à utiliser, l'autre sur l'élément qui suit le dernier que je dois utiliser), et je vais donc demander de "faire quelque chose" pour chaque élément compris entre ces deux bornes
    Je te fais grâce des réflexions qui mêneront à la création de la logique, mais, au final, tu en arriverais donc à une fonction proche de
    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
     
     /* je ne sais pas quel sera le type réel  utilisé" mais, quel qu'il soit, je 
     *dirais qu'il s'appelle emporairement (le temps de l'exécution) iter :D
     */
    template<typename iter>
    std::string lrange(iter begin, // j'ai besoin de la borne de début
                            iter end) // et de la borne de fin 
    {
       /* je pars d'une chaine vide */
       std::string str;
       /* tant que je n'ai pas dépassé le dernier élément que je dois
        * rajouter à ma chaine
        */
       while(begin != end)
       {
           /* je rajoute le contenu de l'élément à ma chaine */
           str+= (*begin);
           /* et je passe à l'élément suivant */
           ++begin;
           /* s'il y a encore un élément à rajouter,
            * j'ajoute un espace pour clairement séparer les différents mots
            */
           if(begin!=end)
               str+=" ";
       }
        /* quand j'arrive ici, j'ai tous les mots, et je peux renvoyer le résultat */
        return str;
    }
    Tu me diras sans doute que cela semble fort proche de ce que l'au aurait pu faire en passant directement des std::vector<std::string>::const_iterator à la fonction, et pourtant...

    Imagine, maintenant, que tu aies:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int main()
    {
        std::string tabC[10]; // un tableau C style de dix chaines
        std::vector<std::string> tabCPP; // un tableau "à la C++"
        std::list<std::string> listeCPP; // et une liste "à la C++"
        // remplissage de tabC, de tabCPP et de listeCPP
        /* comment faire pour récupérer chaque fois une chaine avec 
         * - les éléments de 3 7 inclus de tabC
         * - les éléments compris entre "bonjour" et "world" de tabCpp
         * - l'ensemble des éléments de listeCPP ???
         */
    }
    L'approche "classique" aurait nécessité trois que tu écrives trois versions distinctes de lrange (une pour chaque type de collection envisagé).

    L'approche générique te permet de te contenter d'une seule version, à charge du compilateur de faire le boulot

    La fonction main pourrait donc ressembler à
    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
    int main()
    {
        std::string tabC[10]; // un tableau C style de dix chaines
        std::vector<std::string> tabCPP; // un tableau "à la C++"
        std::list<std::string> listeCPP; // et une liste "à la C++"
        //remplissage de tabC, de tabCPP et de listeCPP
        /* Q :comment faire pour récupérer une chaine avec 
         *  les éléments se trouvant aux indices 3 à 7 inclus de tabC ?
         * R : Simplement en appelant lrange et en passant l'adresse
         * des éléments se trouvant au incides 3 à 8 :
         */
        std::string chaineC=lrange(&tabC[3], &tabC[8]);
     
     
        /* Q : comment faire pour récupérer une chaine avec 
         * les éléments compris entre "bonjour" et "world" de tabCpp
         *  l'ensemble des éléments de listeCPP ?
         * R : en recherchant l'itérateur correspondant à la chaine "bonjour"
         * et un autre à la correspondant ce qui suit la chaine "world" et en les
         * passant à la fonction
         */
        std::vector<std::string>::iterator bVector; // recherche de "bonjour"
        std::vector<std::string >::iterator eVector; // recherche de "world" et
         ++eVector; // passage au suivant
        std::string chaineVector = lrange(bVector,eVector);
        /* Q : comment faire pour récupérer une chaine avec 
         *  l'ensemble des éléments de listeCPP ?
         * R : en transmettant respectivement l'itérateur renvoyé par les 
         * fonctions membres begin et end de la std::list
         */
        std::string chaineListe = lrange(listeCPP.begin(), listeCPP.end());
        return 0;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  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
    Par défaut
    Salut,
    Vas-tu découper une chaine en vecteur pour reconstruire une nouvelle chaîne avec des éléments de ce vecteur, nouvelle chaîne que tu vas peut être redécouper pour construire ....... Bref, est-il vraiment pertinent de retourner une nouvelle chaîne ? Ne souhaiterais-tu pas avoir quelque que chose comme un intervalle sur ton premier vecteur (éventuellement avec un filtre) ? En ce cas, il faudrait regarder des choses comme Boost.Range (et boost.iterators probablement).

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/04/2013, 22h15
  2. Mettre le contenu d'une variable String dans un tableau de String
    Par patriot dans le forum Collection et Stream
    Réponses: 14
    Dernier message: 31/05/2011, 15h25
  3. [String] Remplir un tableau de String à partir d'une boucle "for"
    Par dev197 dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 12/08/2009, 15h29
  4. Impossible d'imprimer une simple String!
    Par nicdo77 dans le forum Langage
    Réponses: 14
    Dernier message: 18/01/2008, 14h57
  5. Réponses: 2
    Dernier message: 10/04/2007, 12h39

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