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 :

stocker les mots dans un tableau


Sujet :

C

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Chercheur en informatique
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Autre

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 8
    Points
    8
    Par défaut stocker les mots dans un tableau
    Bonjour à tous,
    J'ai un souci avec mon code, en fait jai une chaine de caractere dont les mots sont séparés par un espace.
    L'idée de placer les mots dans un tableau donc chaue cellule du tableau va contenir un mot.
    J'ai voulu profiter de la fonction strtok pour faire ca. mais jarrivais pas à mettre les mots dans le tableau
    Avez une idée svp?
    Merci
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(void){
        char s[] = "mot1 mot2 ...";
        char *tok;
     
        tok = strtok(s, " ");
        while(tok != NULL){
            printf("Mot: %s\n", tok);
            tok = strtok(NULL, " ");
        }
     
        return 0;
    }

  2. #2
    Futur Membre du Club
    Femme Profil pro
    Chercheur en informatique
    Inscrit en
    Février 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Autre

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Merci à auteur qui ma aidé sur le chat avec ce bout de 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
        char s[] = "mot1 mot2 mot3 mot4";
        char *tableau[20]={'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0',
                            '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
        char *p;
        int i;
     
        p = strtok(s," ");
     
        i = 0;
        while (p != NULL)
        {
            tableau[i] = p;
            i++;
            p = strtok (NULL, " ");
        }
     
        for (i=0;i<20;i++)
        {
            printf("%s\n",tableau[i]);
        }
     
     
        return 0;
    JE vais le tester

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 900
    Points : 219 891
    Points
    219 891
    Billets dans le blog
    125
    Par défaut
    Bonjour,

    Je pense que vous devez utiliser strtok_r() qui vous renverra tous les éléments.

    Pour copier des mots, n'oubliez pas qu'il faut utiliser strcmp().
    EDIT : Je voulais dire strcpy()

    Finalement, n'oublier pas de supprimer / libérer la mémoire, une fois fini (voir dans la documentation sur qui doit s'occuper de la mémoire, mais là, je pense que c'est vous )

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 900
    Points : 219 891
    Points
    219 891
    Billets dans le blog
    125
    Par défaut
    Bon, strtok, c'est sympa, mais je tiens à rappeler ce que dit la documentation :
    Évitez au maximum d'utiliser cette fonction. Sinon, prenez note des informations suivantes :

    Cette fonction modifie son premier argument.
    Les caractères de séparation sont surchargés, leur identité est donc perdue.
    Cette fonction ne doit pas être invoquée sur une chaîne constante.
    La fonction strtok() utilise un buffer statique et n'est donc pas sûre dans un contexte multithread. Dans ce cas il vaut mieux utiliser strtok_r().
    Note 2 : avec Code::Blocks je n'avais pas strtok_r

    Sinon, cela donne :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    // On compte les mots séparés par sep
    int countSep(const char* phrase, char sep)
    {
        size_t length = strlen(phrase);
        size_t i = 0;
        int counter = 0;
     
        for ( i = 0 ; i < length ; i++ )
        {
            if ( phrase[i] == sep )
            {
                counter++;
            }
        }
     
        // En fait, si on prend ->
        // mot1 mot2
        // On comptera qu'un seul séparateur. Donc il faudra incrémenter pour avoir le nombre exact.
        // Mais si le dernier caractère est un séparateur, nous avons déjà un nombre exact
        if ( phrase[i-1] != sep )
        {
            counter++;
        }
     
        return counter;
    }
     
    int main()
    {
        char s[] = "mot1 mot2 ...";
        char *tok;
     
        // On alloue un tableau de chaines de caractères du nombre de mots que l'on a compté
        char ** words = (char**) malloc(sizeof(char*) * countSep(s,' '));
        if ( words == NULL )
        {
            // EPIC FAIL
            return -1;
        }
     
     
        int wordCounter = 0;
        tok = strtok(s, " ");
        while(tok != NULL)
        {
            words[wordCounter] = tok;
            wordCounter++;
            tok = strtok(NULL, " ");
        }
     
        int i = 0;
        for ( i = 0 ; i < wordCounter ; i++ )
        {
            printf("Mot : %s\n",words[i]);
            // J'en profite pour clean sauf que en fait, y a pas besoin avec strtok (il utilise un buffer static)
            // free(words[i]);
        }
        // Dernier clean (de mon malloc, là haut)
        free(words);
     
    /*
        // Deuxième méthode
        char** tokResult;
        strtok_r(s," ",tokResult);
        for ( i = 0 ; tokResult[i] != NULL ; i++ )
        {
            printf("Mot : %s\n",tokResult[i]);
        }
    */
        return 0;
    }
    Bon, il est très facile de faire des remplacement de strtok avec des strstr , strcpy_n

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    @Scarlet Ibis : Il faut noter sur ce code que :

    0- la chaine s est altérée

    1- tableau est un tableau de pointeurs donc devrait être initialisé à NULL, pas à '\0'

    2- il limite évidemment le nombre de mots à 20

    3- il ne contiendra pas les mots mais l'adresse de début de chaque mot dans la chaine d'origine s. C'est une solution économique et efficace (mais qui ne correspond pas à proprement parler à la question posée) à condition que la chaine s existe encore et est inchangée pendant tout le temps où on utilisera tableau, donc les mots. Ce peut être très limitant comme contrainte et ça dépend du reste du problème.

    @LittleWhite :
    Pour copier des mots, n'oubliez pas qu'il faut utiliser strcmp().
    Tu voulais écrire strcpy()

    Il y a des inconvénients à ce code :

    4- countSep() compte les séparateurs, mais pas les mots (qui peuvent être séparés par un nombre indéterminés de séparateurs consécutifs ou la chaine peut débuter ou se terminer par un ou plusieurs séparateurs).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int countMots(const char* phrase, char sep)
    {
      int count =0;
      do
      {
          while (*phrase != '\0' && *phrase == sep) phrase++;
          if(*phrase != '\0')
          {
              count++;
              while (*phrase != '\0' && *phrase != sep) phrase++;
          }
      } while (*phrase != '\0');
      return count;
    }
    5- La méthode permet de s'affranchir de la restriction sur le nombre de mots, mais conserve les inconvénients cités plus haut en (0) et (3). Il faudrait faire une copie de la chaine d'origine dans un tableau alloué dynamiquement et travailler sur cette copie (strdup() si on dispose de cette fonction).

    6- L'information sur le nombre d'entrée de words est séparée ce qui rendra le code plus difficile à gérer. On a peut être intérêt à agrandir ce tableau d'une case pour y mettre en fin la sentinelle NULL.

    7- Si on retient la solution, évoquée en (5), de dupliquer la chaine , l'information sur l'adresse du début du tableau alloué est disjointe du tableau words (il peut y avoir des séparateurs en tête) ce qui rendra le code plus difficile à gérer. On peut envisager d'agrandir à nouveau le tableau words pour y placer cette adresse (en tête par exemple) ce qui permettra de faire le free() facilement.
    words (allouée dynamiquement) contiendrait alors
    words[0] L'adresse de la chaine dupliquée (allouée dynamiquement)
    words[1]...words[n] L'adresse des n mots dans la chaine dupliquée
    words[n+1] la sentinelle NULL

    D'autres possibilités sont envisageables selon le détail du problème posé. Celle évoquée donne quelque chose comme
    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
    char** chercheMots(const char * s)
    {
        char *dup;
        char *p;
        char **words = NULL;
        int i;
        dup = malloc(strlen(s)+1);
        if(dup != NULL)
        {
           strcpy(dup,s);
           words = malloc( (2+ countMots(dup,' '))*sizeof *words);
           if(words != NULL)
           {
              words[0] = dup;
              p = strtok(dup," ");
              i = 1;
              while (p != NULL)
              {
                  words[i] = p;
                  i++;
                  p = strtok (NULL, " ");
              }
              words[i] = NULL;
           }
           else free(dup);
        }
        return words;
    }
    Avec un exemple d'utilisation :
    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
    void affiche(char** tab)
    {
      tab++;
      while (*tab != NULL)
      {
        printf("%s\n",*tab);
        tab++;
      }
    }
    //---------------------------------------------------------------------------
    int main(void)
    {
        char s[] = "    mot1      mot2 mot3 mot4     ";
        char **words = chercheMots(s);
        if(words != NULL)
        {
          affiche(words);
          free(words[0]);
          free(words);
        }
        return 0;
    }

Discussions similaires

  1. alterner les couleurs dans un tableau avec xsl
    Par Eithelgul dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 03/05/2015, 23h29
  2. stocker les degrès dans la BD postgresql
    Par coquero dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 24/12/2005, 11h47
  3. Trier les données dans 1 tableau par ordre décroissant
    Par Blunet dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 23/11/2005, 09h56
  4. Comment modifier la couleur d'un mot dans un tableau ?
    Par noxious dans le forum Composants VCL
    Réponses: 2
    Dernier message: 16/11/2005, 13h05
  5. Redimensionner les images dans un tableau
    Par cyke37 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 13/10/2005, 19h19

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