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 :

Chaine de caractères --> tableau d'entiers


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut Chaine de caractères --> tableau d'entiers
    Bonjour à tous, je débute en programmation et j'ai un problème sur un exo.
    En fait je récupère une chaine de caractères qui contient des entiers, je dois ensuite utiliser ces entiers pour réaliser des calculs avec. Le problème c'est que je n'arrive pas à utiliser atoi(). Je vous montre mon code ça sera plus simple...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    #include<conio.h>
    int main()
    {
            char *mesures;
            mesures="CHANNELA 0 10 20 30 40 30 20 10 0 -10 -20 -30 -40 -30 -20 -10 -0";
     
            getch();
     
            return 0;
    }
    Le truc c'est que je voudrai mettre mes valeurs numériques dans un tableau d'entiers mais je vois pas comment faire voilà pourquoi je vous demande des conseilles.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par bilowlex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            char *mesures;
            int i=0,j,entiers[100];
            mesures="CHANNELA 0 10 20 30 40 30 20 10 0 -10 -20 -30 -40 -30 -20 -10 -0";
    Le truc c'est que je voudrai mettre mes valeurs numériques dans un tableau d'entiers mais je vois pas comment faire voilà pourquoi je vous demande des conseilles.
    Cherche le premier ' ' avec strchr().
    A partir de là, dans une boucle, utilise strtol() et notamment le 2ème paramètre (lire la doc), pour convertir les éléments de la chaine et les stocker dans le tableau. Fait de ton mieux et poste ton code.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    Tout d'abord merci pour ton aide, par contre je trouve pas la doc de strtol(), il y a pas un endroit sur le site ou je peux le trouver?
    Y a une fonction comme ça il me semble pour les classes java mais j'ai rien trouvé pour le C

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par bilowlex
    Tout d'abord merci pour ton aide, par contre je trouve pas la doc de strlol(), il y a pas un endroit sur le site ou je peux le trouver?
    Y a une fonction comme ça il me semble pour les classes java mais j'ai rien trouvé pour le C
    http://man.developpez.com

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    Oui j'ai vue en me relisant j'ai édité au moment ou vous deviez écrire votre message.
    En fait je comprend pas bien à quoi sert le deuxième paramètre meme avec la documentation (merci pour le lien au passage).
    Dans mon cas ça voudrais dire que les "9 premières cases" de ma chaine de caractères sont des erreurs?
    N'y a t'il pas un moyen de commencé la lecture à un certain endroit du tableau?
    Par exemple je comme à 9 (comme ça j'ai le zéro), ensuite espace donc entier[0]=0, puis il continue à 11 j'ai un 1 puis pas d'espace donc 0.... entier[1]=10 ?
    je sais pas si c'est très clair j'en doute meme mais je sais pas trop comment expliqué

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Par défaut
    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
     
    int main()                                                                                                            
    {                                                                                                                     
      char  *mesures;                                                                                                     
      int   i, j, tab[256], nb;                                                                                           
     
      mesures = "CHANNELA 0 10 20 30 40 30 20 10 0 -10 -20 -30 -40 -30 -20 -10 -1";                                       
     
      /*Recherche du premier entier*/
      for (i = 0; mesures[i] && mesures[i] != '-' && (mesures[i] > '9' || mesures[i] < '0'); i++);                        
      /*J'ajoute dans un tableau d'entier en passant a atoi() tous le reste de la chaine, il coupe automatiquement des qu'il voit que le caractere n'est pas entre 0 et 9...*/
      for (j = 0, nb = 0; mesures[i]; j++, i++, nb++)                                                                     
      {                                                                                                                   
        tab[j] = atoi(mesures + i);
        /* Je recherche le  premier espace  pour la prochaine iteration */                                                                                       
        for (; mesures[i] && mesures[i] != ' '; i++);                                                                
        /* i est l'index de l'espace, je l'incremente pour le caractere suivant, j'incremente l'index j de mon tableau d'entier, et nb, le nombre d'entier dans le tableau */     
      }                                                                                                                   
      for (j = 0; j < nb - 1; j++)                                                                                        
        printf("%d\n", tab[j]);                                                                                           
      printf("%s\n", mesures);                                                                                            
      return 0;                                                                                                           
    }
    Ceci est un exemple si jamais tu as un probleme pour comprendre ce code n'hesite pas a poster.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 26
    Par défaut
    Merci beaucoup,
    Grace au commentaires présent sur le code j'ai bien compris les différents étapes.
    En fait mon problème était de trouver le premier entier, et je n'avais pas penser à arrété lorsque le char n'était pas entre 0 9
    En tout cas merci à tous les deux pour votre aide

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par bilowlex
    En fait je comprend pas bien à quoi sert le deuxième paramètre meme avec la documentation (merci pour le lien au passage).
    Oui, ce n'est pas trivial, je l'admet.
    Dans mon cas ça voudrais dire que les "9 premières cases" de ma chaine de caractères sont des erreurs?
    N'y a t'il pas un moyen de commencé la lecture à un certain endroit du tableau?
    Par exemple je comme à 9 (comme ça j'ai le zéro), ensuite espace donc entier[0]=0, puis il continue à 11 j'ai un 1 puis pas d'espace donc 0.... entier[1]=10 ?
    je sais pas si c'est très clair j'en doute meme mais je sais pas trop comment expliqué
    C'est à peu près bien expliqué. Ce qui te manque c'est un peu d'expérience en matière d'analyse de chaine de caractères.
    1. D'après l'exemple fourni, je tire quelques hypothèses de travail concernant le format des données à extraire.
      • Les données sont représentées par une chaine de caractères.
      • La chaine est divisées en mots séparés par un espaces.
      • Le premier mot doit être ignoré
      • Les 17 mots suivants représentent de valeurs numériques signées codées en décimal.

      Si ces informations sont erronées, merci de les corriger. (toute la suite repose dessus !)
    2. En fonction des informations ci-dessus, et du problème posé qui est 'récupérer les valeurs numériques dans un tableau", déduire l'algorithme, c'est à dire le comportement du programme qui doit analyser la chaine
      • Algorithme textuel

        "Analyse de la chaine en vu d'en tirer les valeurs numériques"
        • Commencer l'analyse de la chaine en ignorant le premier mot
        • Pour chaque mots suivants,
          • convertir le mot en valeur numérique
          • stocker la valeur dans un tableau à la case suivante

      • Algorithme formel en pseudo-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
         
        ; "Analyse de la chaine en vu d'en tirer les valeurs numériques"
        BEGIN
         tableau ARRAY OF 17 INTEGERS
        ; Commencer l'analyse de la chaine en ignorant le premier mot
         p := chercher_caractere (chaine, ' ')
        ; Pour chaque mots suivants, 
         i := 0
         WHILE p <> NIL AND (p) <> END OF STRING
        ; convertir le mot en valeur numérique 
          valeur := convertir (p, DECIMAL)
        ; chercher le mot suivant
          p := chercher_caractere (chaine, ' ')
        ; stocker la valeur dans un tableau à la case suivante
          tableau[i] := valeur
          INC (i)
         END WHILE
        END

    Les deux fonctions restant à définir sont
    chercher_caractere() et convertir().

    Avant de réinventer la roue on peut consulter la liste des fonctions standards du C. Or, il se trouve précisément que, ce genre d'opérations étant courante, il existe des fonctions standards qui répondent à ces questions :
    • recherche d'un caractère dans une chaine : strchr()
    • conversion d'un chaine en nombre : strtol()

    strchr() est trivial, je n'insiste pas.

    Si on étudie en détail l'interface de strtol(), on constate que le premier paramètre concerne la chaine à traduire. Jusque là ça va. Le second est un peu mystérieux, on y reviendra, et le troisième est la base de conversion. Pour 'décimal', on met 10.

    Que dit la doc à propos du deuxième paramètre ? Déjà, que si on ne veut pas l'utiliser, on peut le mettre à NULL.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       valeur = strtol ("123", NULL 10);
    On voit déjà comment faire la conversion.

    On pourrait coder l'algorithme comme ceci :

    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
     
    /* "Analyse de la chaine en vu d'en tirer les valeurs numériques" */
     
    /* BEGIN */
    int main (void)
    {
    /* tableau ARRAY OF 17 INTEGERS */
       int tableau[17];
     
    /* p := chercher_caractere (chaine, ' ') */
       char *p = strchr(chaine, ' ');
     
    /* WHILE p <> NIL AND (p) <> END OF STRING */
       while (p != NULL && *p != 0)
       {
     
    /*   valeur := convertir (p, DECIMAL) */
         int valeur = strtol (p, NULL 10);
     
    /*   p := chercher_caractere (chaine, ' ') */
          char *p = strchr(chaine, ' ');
     
    /*   tableau[i] := valeur */
          tableau[i] = valeur;
     
    /*   INC (i) */
          i++;
     
    /* END WHILE */
       }
    /* END */
       return 0;
    }
    Ne reste plus qu'à finaliser (chaine, prototypes des fonctions)
    et on a une solution viable.

    Mais, et c'est là qu'il vaut être un peu curieux, est-ce que ce mystérieux 2ème paramètre n'aurait pas une rôle qui pourrait nous aider ?

    On relis la doc, qui dit en substance :
    - La conversion s'arrête dès qu'un caractère non convertible est rencontré. (par exemple ' ', le séparateur de mots)
    - Le deuxième paramètre reçoit l'adresse d'un pointeur sur char (d'où le type char **) qui est modifié par la fonction de façon à pointer sur le premier caractère non traduit.

    Il faut le relire plusieurs fois, et surtout en tirer les conclusions qui s'imposent, à savoir que si on a une conversion à faire "123", le pointeur de fin de conversion pointe sur le 0 final de la chaine. Par contre, si il y a plusieurs mots dans la chaine : "123 456", le pointeur de fin de conversion pointe sur l'espace . Pour convertir le nombre suivant, il suffit donc de repartir de cet espace : " 456" (la doc dit aussi que les espaces précédant les nombres sont ignorés).

    On voit donc que grâce à ce stratagème (prévu pour ça, évidemment), il est très simple d'analyser une chaine contenant plusieurs nombres à convertir. Il suffit de boucler jusqu à ce que le pointeur de fin pointe sur le 0 final.

    On voit donc que l'implémentation de l'algorithme précédent peut être simplifiée ainsi :
    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
     
    /* "Analyse de la chaine en vu d'en tirer les valeurs numériques" */
     
    /* BEGIN */
    int main (void)
    {
    /* tableau ARRAY OF 17 INTEGERS */
       int tableau[17];
     
    /* p := chercher_caractere (chaine, ' ') */
       char *p = strchr(chaine, ' ');
     
    /* WHILE p <> NIL AND (p) <> END OF STRING */
       while (p != NULL && *p != 0)
       {
     
    /*   valeur := convertir (p, DECIMAL) */
    /*   p := chercher_caractere (chaine, ' ') */
         int valeur = strtol (p, &p 10);
     
    /*   tableau[i] := valeur */
          tableau[i] = valeur;
     
    /*   INC (i) */
          i++;
     
    /* END WHILE */
       }
    /* END */
       return 0;
    }
    La conversion et la recherche du mot suivant sont combinés en une seule opération.

    La simple analyse descendante n'avait pas permis de trouver cette simplification.

    Seule une bonne connaissance des possibilité de la bibliothèque permet d'améliorer l'implémentation en utilisant les mécanismes existants.

    C'est le petit cours de C du samedi après midi...

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

Discussions similaires

  1. [Débutant] Transformer une chaine de caractères en tableau
    Par Manou26 dans le forum MATLAB
    Réponses: 2
    Dernier message: 21/11/2013, 16h57
  2. Chaine de caractères et tableau
    Par Garamante dans le forum VBScript
    Réponses: 10
    Dernier message: 13/12/2008, 12h27
  3. Chaine de caractère et tableau
    Par Garamante dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 12/12/2008, 16h26
  4. [RegEx] Ajouter une chaine de caractères à un tableau
    Par the magic developer dans le forum Langage
    Réponses: 10
    Dernier message: 03/11/2008, 10h14
  5. Convertir une chaine de caractère en tableau
    Par Mysti¢ dans le forum Général Python
    Réponses: 7
    Dernier message: 09/04/2007, 12h20

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