Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction qui sépare les mots

Sujet résolu
Anonyme
    25 janvier 2020 à 16:29:46

    Bonjour. Alors voilà, je dois créer une fonction sépare les mots dans une phrase et mon idée est de créer un tableau où l'indice 0 est le premier mot et ainsi de suite. Voici mon code, pour la fonction qui compte les mots je n'ai aucun souci mais le problème c'est la fonction où je déclare comment se fait la séparation. Il n'y a plus d'erreur de compilation mais il n'y a rien qui apparaît après exécution. Si vous pouviez me dire où est-ce que j'ai fait une erreur, s'il vous plaît.

    #include "stdio.h"
    

    include "string.h"

    include "stdlib.h"

    int compter_les_mots(char*phrase) {

    int compteur=0;int i=0;
    while(phrase[i]!='\0')
    {
        if(phrase[i]==' ')
        {
            compteur++;
        }
        i++;
    }
    return compteur;
    

    } char**allouer2D(int) {

    int taillemot=strlen(phrase);
    char**liste_mot=malloc(compter_les_mots(phrase));
    for(int i=0; i<(compter_les_mots(phrase));i++;
    {
        liste_mot[i]=malloc(taillemot);
    }
    for(int i=0; i&lt;taillemot i="" int="" j="0;" while="" if="" phrase="" return="" liste_mot="" void="" main="" char="" strcpy="" veux="" une="" fleur="" printf="" la="" r="" est="" /&gt;</pre>
    
    </pre>

    -
    Edité par Anonyme 25 janvier 2020 à 17:58:59

    • Partager sur Facebook
    • Partager sur Twitter
      25 janvier 2020 à 17:54:42

      Hello,

      strtok() ?

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

      Anonyme
        25 janvier 2020 à 18:02:46

        Bonjour

        edgarjacobs a écrit: >

        Oui je connais l'existence de strtok() et ça m'arrangerai vraiment de pouvoir l'utiliser mais nous ne pouvons pas. Notre devoir est de créer justement une fonction qui ferait le même travail.

        • Partager sur Facebook
        • Partager sur Twitter
          25 janvier 2020 à 18:06:16

          strtok modifie la ligne qu'elle parcourt. Et elle fait des horreurs qui la rendent inutilisables par des threads (elle contient une variable statique qui sert d'itérateur).

          BUGS
                 Be cautious when using these functions.  If you do use them, note that:
          
                 * These functions modify their first argument.
          
                 * These functions cannot be used on constant strings.
          
                 * The identity of the delimiting byte is lost.
          
                 * The strtok() function uses a static buffer while parsing, so it's not
                   thread safe.  Use strtok_r() if this matters to you.
          

          Ce n'est donc pas un modèle à suivre (ni un truc à employer sans y avoir réfléchi, you script kiddies).

          Par ailleurs, si vous pompez le code de strtok, ça va se voir.

          https://www.google.com/search?q=strtok+code

          ---

          Il s'agit ici d'un exercice. La première question à se poser, c'est ce que ça doit faire exactement. La programmation, ça vient après. Si  on appelle

          decouper_en_mots("   Voyons, est-ce que ça va marcher ?");
          

          qu'est-ce que ça doit retourner exactement ?

          PS: compter les mots à partir du nombre d'espaces, ça va pas le faire. Les espaces peuvent être répétés, et en début/fin de chaine.

          Indication : un mot, ça commence par un début de mot. C'est quand il y a une lettre qui n'est pas précédée d'une autre lettre.

          PS: comme la fonction strtok m'énerve, j'ai écrit un remplacement qui n'a pas les défauts signalés

          https://github.com/MichelBillaud/tools-for-teaching/tree/master/Replacement-for-strtok

          -
          Edité par michelbillaud 25 janvier 2020 à 20:50:23

          • Partager sur Facebook
          • Partager sur Twitter
            26 janvier 2020 à 2:42:48

            @michelbillaud: et s'il copie ton code, ça ne se saura pas?
            Dans l'exemple, il n'y a que les espaces comme séparateur.
            Dans "la vraie vie", il y a toutes les ponctuations: ',' '.' ';' ':' '(' ')' etc.
            Comme l'a dit michelbillaud, il ne faut pas considérer les séparateurs mais seulement les mots. Que fait-tu des mots avec apostrophe comme l'école ou aujourd'hui?
            Ensuite, il faut se demander si on peut détruire la chaîne d'origine ou pas.
            Si on peut la détruire, on peut mettre des '\0' après chaque mot, sinon on devra les recopier dans une nouvelle chaîne réservée par malloc.
            En passant, l'espace total réservé pour les mots ne peut dépasser l'espace de la chaîne d'origine.
            Si on n'est pas à court de mémoire, on peut donc réserver cet espace dès le début.
            On pourra recopier chaque mot suivi de son terminateur ('\0') en même temps qu'on parcourt la chaîne d'origine.
            Ce sera plus facile de parcourir cette nouvelle "suite de chaînes" pour trouver les pointeurs qu'on mettra dans notre tableau.
            En comptant les mots, on saura la grandeur du tableau à réserver

            -
            Edité par PierrotLeFou 26 janvier 2020 à 3:51:11

            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              26 janvier 2020 à 8:44:53

              @pierrot on sépare facilement les codes produits par 95% des étudiants, de ce qui est écrit avec un peu d'expérience.

              Compare la version gnu de strtok_r, et celle de bsd, avec ses gotos.

              • Partager sur Facebook
              • Partager sur Twitter
                26 janvier 2020 à 9:29:41

                Salut,

                Ce sujet.

                • Partager sur Facebook
                • Partager sur Twitter

                Bonhomme !! | Jeu de plateforme : Prototype.

                Anonyme
                  26 janvier 2020 à 14:08:07

                  Bonjour Alors voilà, j'ai bien bien noté qu'il y a d'autres séparateurs et que je devrais prendre en compte les mots et non eux. C n'est pas que je ne veuille pas suivre vos conseils mais auparavant on nous avait demandé de compter les mots en fonctions à l'aide d'un espace et dans ce devoir-ci de l'utiliser d'où mon utilisation. Ensuite voilà ce que j'ai fait en suivant vos indications 1-créer un tableau vide qui pourrait contenir les mots trouvés 2-j'ai placé les mots dans le tableau vide a) à chaque fois qu'il y a un espace, je le remplace par '\0' dans le tableau vide b) si ce n'est pas un espace je copie les caractère dans le tableau vide Une 1ère boucle parcoure la phrase initiale, une 2em qui limite les ligne du tableaux, une 2em les colonnes. Je suis un peu perdue dans la façon de copier les mots dans le tableau vide. (Autre consigne qu'on nous a donné"ne pas utiliser scanf)

                  charlocation2(char*phrase, int ligne, int colonne)
                  {
                  int i;
                  int nbmot=count(phrase);
                  char**logement=malloc(nbmot*sizeof(char));
                  for(i=0; i<nbmot logement="" return="" class="brush c;">charplace_split(char*phrase)
                  {
                  int i ; int j ; int a ; int ligne ; int colonne ; 
                  ligne=count(phrase) ; 
                  colonne=strlen(phrase) ; 
                  char**louer=location2(phrase, ligne, colonne) ; 
                  for(a=0 ;  phrase[a] ! ='\0' ; a++)
                  {
                  for(i=0 ;  i<ligne i="" for="" j="" if="" louer="" else="" a="" return="" /></nbmot>

                  -
                  Edité par Anonyme 26 janvier 2020 à 15:21:45

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 janvier 2020 à 15:40:37

                    Je ne vois pas l'utilité de scanf ici. C'est un drôle d'exercice que de compter les mots avec les espaces.
                    Cela suppose que la phrase commence bien par une lettre et ne contient pas de double espace. Et pour le dernier mot?
                    Si c'est le contexte dans lequel tu dois travailler, alors c'est correct que de remplacer les espaces par '\0'
                    Si tu comptes les mots comme tu le fais, tu sais l'espace à demander à malloc pour réserver ton tableau.
                    C'est inutile de mettre 'sizeof(char)', ça vaut toujours '1'. Par contre 'sizeof(*char)' est la longueur d'un pointeur vers une chaîne.
                    j'ai dit une connerie, c'est (char *) ...
                    Tu parcours ta "suite de chaînes" comme j'ai dit. Tu mets dans les casses successives de ton tableau la position de la première lettre de chaque mot.

                    -
                    Edité par PierrotLeFou 27 janvier 2020 à 6:37:25

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Le Tout est souvent plus grand que la somme de ses parties.

                      26 janvier 2020 à 16:17:41

                      L'exercice devait être assaisonné d'indications simplificatrices : << on considérera que les mots sont des suites de lettres, et qu'ils sont séparés par des espaces. >>

                      Avec cette simplification (outrancière), il y a un mot chaque fois qu'on rencontre un lettre qui n'est pas précédée d'une autre lettre (= un espace).

                      nbMots = 0
                      dansMot = faux
                      
                      pour tout caractere c de la chaine
                        si c est une lettre et pas dansMot
                                augmenter nbMots
                        dansMot = (c est une lettre)
                             
                      


                      Il ne suffit pas "de compter les espaces". On compte les fois où on passe d'un espace à une lettre.

                      -
                      Edité par michelbillaud 26 janvier 2020 à 16:18:58

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        26 janvier 2020 à 17:47:45

                        @PierrotLeFou. J'ai saisi l'idée de parcourir et copier et j'ai écrit ceci. J'hésite entre ce que je dois écrire en premier : remplacer les espaces en \0 ou d'abord copier le mot dans le tableau créer précédemment. char*place_split(charphrase) { int i=0 ; int j=0 ; int taille(count(phrase) ; int capacité=strlen(phrase) ; Char**lm=location2(phrase,taille,capacité) ; For(int a=0 ; phrase[a] ! ='\0 ' ; a++ ; { while(phrase[a] ! =' ') { lm[i][j]=phrase[a] ; a++ ; } phrase[a]='\0' ; lm[i][j]=phrase[a] ; lm[i+1]=phrase[a] a++ ; } lm[i][j]=phrase[a] ; } return lm ; }

                        • Partager sur Facebook
                        • Partager sur Twitter
                          26 janvier 2020 à 17:59:27

                          > J'hésite entre ce que je dois écrire en premier

                          Fais les deux, et puis compare.

                          Arrête d'hésiter.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 janvier 2020 à 7:10:19

                            « c'est en forgeant qu'on devient forgeron »
                            @HasinaSitraka:
                            Tu dis que tu veux «créer un tableau vide», C'est censé vouloir dire quoi?
                            Je ne vois pas où tu veux en venir avec les lignes et colonnes du tableau.
                            Le premier indice sera le numéro du mot et le second indice sera le numéro du caractère dans le mot.
                            Je rappelle que tu dois connaître le nombre de mots dans ta phrase avant de réserver ton tableau
                            (on ne va pas lui montrer le realloc() ...)
                            Si tu remplaces les espaces par des '\0' et que tu te fies sur les espaces pour compter les mots, tiens compte du fait que le dernier mot peut ne pas être suivi d'un espace.
                            Si tu recopies dans une nouvelle chaîne, n'oublies pas de réserver l'espace pour le '\0' de fin de chaîne.
                            Petit indice: que veut dire tableau[n] = &chaine[i]; ?
                            Ça te servira pour placer les pointeurs vers les mots dans ton tableau.
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Le Tout est souvent plus grand que la somme de ses parties.

                              27 janvier 2020 à 9:49:45

                              Les débutants s'imaginent souvent que les solutions viennent toutes seules, après une idée géniale comme "je vais commencer par créer une variable".

                              Comme on leur dit qu'une fonction commence par des déclarations de variables, ils pensent avoir fait le début du boulot :-)

                              C'est bien de se dire "je vais décomposer la phrase en mots, et coller chacun dans un tableau". Mais déjà, pour réserver le tableau, il faut savoir combien il y en a. La déclaration du tableau, elle donc vient après un comptage des mots. Et la copie des mots dans le tableau, elle vient après la réservation. Ou alors c'est qu'on gère un tableau extensible (à ce niveau d'apprentissage ?).

                              Important : faire un petit dessin, ça aide. Voila par exemple l'approche "on travaille dans la chaine, on note où se trouvent les débuts de mots, et on met des 0 à la fin".

                               ce qui donne les étapes

                              - compter les mots

                              - réserver le tableau de pointeurs

                              - parcourir pour noter les débuts, et marquer les fins.

                              -
                              Edité par michelbillaud 27 janvier 2020 à 10:02:21

                              • Partager sur Facebook
                              • Partager sur Twitter
                                27 janvier 2020 à 18:49:26

                                Je me suis tapé l'exercice pour voir. J'ai décidé de ré-écrire sur place.
                                (j'aurais pu faire un malloc et réserver une longueur éqquivalente à la chaîne, puis recopier)
                                Dans ma première étape, je compte les mots et je marque les fins de mots.
                                Justement, mon dernier mot ne se terminait pas par un espace et je me suis fait jouer un tour (d'où mon commentaire)
                                Je réserve ensuite le tableau des pointeurs vers les chaînes.
                                Dans la seconde étape, je parcours la nouvelle chaîne en assignant le début de mot à un pointeur que je place dans le tableau.
                                (je parle de "chaîne" mais j'ai utilisé le terme "suite de chaînes")
                                À la fin, j'affiche le tableau et les mots sont bien là et séparés.
                                Pour un débutant, il est facile de mêler les tableaux à deux dimensions et les tableaux de chaînes car ils semblent de deux dimensions.
                                À cette différence près que les chaînes ne sont pas toutes de la même longueur.
                                Ils ne comprennent pas qu'il faut mettre un pointeur vers le premier caractère de la chaîne et non le caractère lui-même.
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Le Tout est souvent plus grand que la somme de ses parties.

                                Anonyme
                                  6 février 2020 à 17:52:18

                                  Bonsoir ! Je tiens avant tout à m'excuser pour ne plus avoir répondu et ne pas avoir dit ceci plus tôt. J'ai résolu ce problème il y a quelques semaines et je vous remercie pour toute votre aide !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    6 février 2020 à 17:56:44

                                    Bonjour,

                                    Sujet résolu

                                    Tu peux passer le sujet à "résolu" (bouton en haut à droite du sujet) et cliquer sur les pouces levés des messages qui t'ont aidé⋅e ;)
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Fonction qui sépare les mots

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown