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 :

Séparation des mots d'une chaine


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2003
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 42
    Points : 35
    Points
    35
    Par défaut Séparation des mots d'une chaine
    Bonjour à tous,

    Après avoir arrêté la programmation pendant environ un an et demi je m'y remets mais je dois avouer que je dois travailler pour retrouver mes réflex d'antan.

    J'ai trouvé un exercice sur internet qui consiste à programmer une fonction qui prend en paramètre une chaine de caractère et qui retourne lors de chaque appel successif le mots successifs de la chaine initiale à condition de lui passer NULL en argument.

    De mémoire cela ressemble à une fonction de la bibliothèque standard (strtok si je me souviens bien)

    voici le code

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    #include <iostream>
    #include <cstdlib>
     
    #define MAX 80
    using namespace std ;
     
     
    // 23-06-07
     
    // Programme permettant la saisie d'une chaine, puis son extraction mot par mot à la manière de la fonction
     
    char* split_word(char*) ;
     
    int main()
    {
    	char* pchaine ;
    	char* display ;
    	int i = 0, count = 0 ;
     
    	pchaine = new char[MAX] ;
    	if(!pchaine)
    	{
    	    cout << "Mémoire insuffisante ! " ;
    	    exit(1) ;
    	}
     
    	cout << endl
             << "Saisissez votre chaine :"
             << endl ;
        cin.getline(pchaine, MAX, '\n') ;
     
        while (*(pchaine + i) != '\0') // boucle permettant de compter le nombre d'espace dans la chaine
        {
            if(*(pchaine + i) != ' ')
                count++ ;
            i++ ;
        }
     
        cout << split_word(pchaine) ; // affiche le premier mots
     
        for(i=1 ; i <= count ; i++)
        {
            display = split_word(NULL) ;
            cout<< endl
                << display
                << endl ;
                delete [] display ;
        }
     
     
    	return 0;
    }
     
    // fonction retournant le mot suivant d'une chaine initiale si on lui passe NULL en paramètre sinon recommence si on lui passe une
    // chaine de caractères.
    char* split_word(char* chaine_input)
    {
        static char* chaine_m ; // chaine mémorisée
        char* buffer = NULL ; //chaine tampon pour raccourcir celle d'avant.
        char* mot = NULL; // chaine de retour
        int length=0, j=0 ;
     
        if((chaine_input == NULL)) //on affiche le mot suivant si on reçoit NULL en paramètre
        {
            while(*(chaine_m + length) != ' ') // compte le nombre de caractères  avant l'espace suivant
            {
                length++ ;
            }
     
            mot = new char[length] ; // on crée une chaine de la longueur du mot.
            if (!mot)
            {
                cout << "Mémoire insuffisante" ;
                exit(1) ;
            }
     
            for(j=0; j<length; j++)
            {
                *(mot + j) = *(chaine_m + j) ; // copie des lettre du mots dans *word
            }
     
            buffer = chaine_m ; // charge le tampon
            j=0 ;
     
            while (*(chaine_m+j) != '\0')
            {
                *(chaine_m + j) = *(buffer + j + length) ;
                j++ ;
            }
     
     
        }
        else // on sélectionne la chaine en entrée
        {
            chaine_m = chaine_input ;
     
        }
        cout << mot ;
     
     
        return mot ;
    }
    Je compile avec Code Block, pas de soucis la compilation marche bien, mais l'ennui c'est que le programme en lui même ne m'affiche aucune réponse, juste l'invite pour saisir la chaine de départ, mais il ne me la divise pas en mots successif avec la boucle for du main.

    Suite à un rapide tour par le debugger, me montre que apparament les boucles et la fonction split_word s'effectuent bien.

    Donc ne voyant pas d'où peut venir le problème, je me tourne vers vous qui m'avez tant de fois dépanner par le passé.

    Si vous pouvez m'éclairer dans mon problème.

    D'avance merci

    Lvdnono

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut,
    je pense que tu as pour commencer une erreur sur le comptatge des mots;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
       while (*(pchaine + i) != '\0') // boucle permettant de compter le nombre d'espace dans la chaine
        {
            if(*(pchaine + i) == ' ')  // au lieu de !=
                count++ ;
            i++ ;
        }
    ensuite dans t'as fonction ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     mot = new char[length+1] ; // on crée une chaine de la longueur du mot.
            if (!mot)
            {
                cout << "Mémoire insuffisante" ;
                exit(1) ;
            }
     
            for(j=0; j<length; j++)
            {
                *(mot + j) = *(chaine_m + j) ; // copie des lettre du mots dans *word
            }
    *(mot +length) = '\0';

    Mais comme tu creer de la memoire dynamic, tu genere une fuite memoire...

    Peut tu modifier la chaine que tu donne en entré?
    si tu peut utilise strok.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Avril 2003
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 42
    Points : 35
    Points
    35
    Par défaut
    Merci Mongaulois, en effet j'avais pas réalisé que la fonction ne rajoutait pas le /0 en fin de chaine retournée !

    Cependant je ne comprend pas pourquoi il y a une fuite mémoire, puisque que la mémoire que j'alloue dans la fonction split_word, je la libère juste après dans la boucle for du main avec un "delete [] display ;" or display et mot pointe sur le même élément non ? Donc je n'arrive pas à voir ou se situe la fuite mémoire.

    Si vous pouviez m'éclairer sur ce point

    Merci pour ce début de réponse très rapide et qui fait avancer le schmilblik

    Lvdnono

    PS : L'intérêt de recopier chaque mot ... euh ben disons qu'il est faible, mais j'aimerai bien m'entrainer à tout ce qui est allocation dynamique et pointeur donc même si ça complexifie un peu le code, ça me permet de faire des erreurs et donc de progresser (et aussi de vous poser des questions sans doute débile ... )

    cependant je suis d'accord que je pourrais faire un static int qui compte le nombre d'appel et qui renvoie alors le nième mots de la chaine.

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 753
    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 753
    Points : 10 704
    Points
    10 704
    Billets dans le blog
    3
    Par défaut
    Ton test
    ne sert a rien vu qu'une exception est levée en cas de mémoire insuffisante.

    Parcours un peu la FAQ, et apprend a utiliser std::string:
    http://c.developpez.com/faq/cpp/?page=strings

    http://c.developpez.com/faq/cpp/?pag...#STRING_tokens

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    je n'avais pas vu (c'est pas trés propre)
    par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << split_word(pchaine) ;
    je sais pas trop ce que ça va faire, tu retourne NULL

  6. #6
    Nouveau membre du Club
    Inscrit en
    Avril 2003
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 42
    Points : 35
    Points
    35
    Par défaut
    J'ai essayé avec les std::string: et c'est nettement plus facile, donc j'ai résolu mon problème.

    Je tire juste mon chapeau au développer en C qui ont été capable de développer strtok, parce que c'est pas si simple qu'il n'y parait

    Pour la remarque de mongaulois je suis d'accord avec la remarque et je l'ai corrigé mais la source initiale ne fonctionne pas mieux.

    Encore merci pour votre aide.

    Lvdnono

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

Discussions similaires

  1. Extraction des mots d'une chaine de caractere
    Par ahd261 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 09/04/2009, 19h16
  2. Réponses: 0
    Dernier message: 27/12/2008, 23h49
  3. Réponses: 5
    Dernier message: 01/07/2008, 16h36
  4. [Tableaux] Extraire des mots d'une chaine de caractères
    Par pratiquement dans le forum Langage
    Réponses: 5
    Dernier message: 24/01/2008, 09h20
  5. Réponses: 5
    Dernier message: 21/01/2007, 00h43

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