Bonjour,
j'aimerais passer d'une chaine de caractères de type " 12 45 2 8 " à une liste d'entiers. je pense qu'il faut utiliser sscanf mais je sais pas comment
merci en avance
Bonjour,
j'aimerais passer d'une chaine de caractères de type " 12 45 2 8 " à une liste d'entiers. je pense qu'il faut utiliser sscanf mais je sais pas comment
merci en avance
le premier point à résoudre c'est le nombre de passes et le container pour stocker les valeurs.
Si tu optes pour 1 stockage "fixe" (comme 1 tableau par exemple), alors il te faut 1 algo en 2 passes : 1 pour calculer le nombre de valeurs, 1 pour le stockage (après avoir fait l'initialisation de ton stockage)
Si tu optes pour 1 stockage dynamique (comme 1 tableau dynamique ou 1 liste [doublement] chainée par exemple), alors il te faut seulement 1 passe.
Ensuite pour répondre à ta question sscanf. Le problème, c'est que tu ne connais pas le nombre de valeurs dans ta chaîne
Tu peux éventuellement contruire le format lors d'1 ou plusieurs passes, mais comment passer 1 nombre variable de valeurs ?
En C, il y a l'ellipse (documentation cplusplus.com de l'entête stdarg.h en anglais)
Mais cela semble foireux
Il faut faire 1 machine à états :
*) debut : c'est l'état space
Ensuite il faut statuer si 1 chaine vide/ avec que des espaces est 1 erreur ou pas. Si c'est 1 erreur, le début est 1 état space avec la fin de tableau qui passe à l'état error.
*) état number : tant qu'on a 1 chiffre, on continue.
Si on a 1 espace, on passe à l'état space
Si on a 1 fin de tableau, on a fini.
Tout autre caractère, on passe à l'état error
Ici la formule mathématique est : on prend 1 chiffre X, le nombre qu'on extrait vaut current_nombre = ((current_nombre * 10) + X) (par défaut, current_nombre=0).
*) état space : tant qu'on a 1 espace, on continue.
Si on a 1 chiffre, on passe à l'état number
Si on a 1 fin de tableau, on a fini.
Tout autre caractère, on passe à l'état error
Bonjour,
La donnée importante en effet est la gestion d'un nombre variable données à lire. Si par contre le nombre est fixe et qu'il y en a peu, on peut tout à fait utiliser sscanf().
Sinon tu devras traiter les nombres un par un et en stocker le résultat.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 char buffer_in[] = " 12 45 2 8 "; int tab[4]; sscanf( buffer_in, "%d%d%d%d", tab, tab+1, tab+2, tab+3 );
Dans ce cas tu as la fonction strtol() qui fait presque tout le boulot indiqué par foetus. Elle sait sauter les espaces, sait extraire le nombre entier et sait dire où dans la chaîne le nombre se termine.
Si on ne connaît pas le nombre maximum de données à lire, un simple tableau ne pourra pas être utilisé. Il te faut faire de l'allocation dynamique. Là ça peux devenir complexe en fonction de ton besoin. Tu peux par exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 int index = 0; const char* pos = buffer_in; // on part du début de la chaîne for (;;) { char** la_fin; while ( pos == ' ' ) // se placer au début du prochain nombre ++pos; int valeur_lue = strtol( pos , &la_fin, 10 ); if ( str_end == pos ) // pas vu de nombre entier; c'est fini break; tab[index++] = valeur_lue; pos = la_fin; // se positionner sur la suite à lire }
- effectuer toute la lecture sans jamais stocker la valeur_lue. A la fin tu as le nombre dans index, tu peux faire l'allocation nécessaire, et tu recommences et cette fois tu peux stocker tes valeur_lue.
- compter le nombre d'espaces et en déduire le nombre d'éléments avant de les lire. Méthode piégeuse, y a-t-il des espaces au début, à fin, plusieurs successifs?
- extraire les données successivement et réallouer à chaque fois le tableau résultat avec la fonction realloc().
Effectivement, je suis resté sur la fonction sscanf sans chercher + loin
On peut faire 1 boucle avec la fonction strtol : il reste à tester la gestion des espaces, et notamment en début de chaîne.
documentation de la fonction strtol sur cplusplus.com en anglais
Je parle de tableau dynamique qui ajoute X éléments à la fin lorsqu'il est plein (avec 1 realloc)
Réallouer le tableau 1 élément par 1 élément ne me semble pas très efficace
Bonjour
Si tu n'as pas peur de perdre ta string intiale, tu peux utiliser strtok_r(). Comme je le dis, son inconvénient est qu'elle modifie la string qu'elle traite et donc en fin de traitement, la string initiale n'est plus du tout ce qu'elle était. Accessoirement la string soit impérativement être modifiable (interdit de traiter par exemple un char *buffer_int=" 12 45 32 8 ").
Mais si tout ça ne te gêne pas, alors cette fonction est bien pratique. Exemple
A la place de printf() tu peux utiliser ensuite strtol().
Code c : 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 <string.h> int main() { char buffer_int[]=" 12 45 32 8 "; char *pt; char *w; for (pt=strtok_r(buffer_int, " ", &w); pt != NULL; pt=strtok_r(NULL, " ", &w)) { printf("[%s]\n", pt); } }
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager