Go Down

Topic: Isoler différentes parties d'une chaine de caractères (Read 148 times) previous topic - next topic

SimonGEII

Bonjour à tous,

Je ne suis pas très expérimenté dans la programmation Arduino et je me demande comment faire ceci :

Je reçois une chaine de caractère ressemblant à : 10010\AE200\EP550\P

que je voudrais séparer en trois chaines différentes avec la première chaine égale à 10010, la deuxième égale à E200 et la troisième à P550

sachant que le \A, \E et le \P signifie la fin de trois informations différentes.

Désolé si je ne suis pas clair mais je n'arrive pas à mieux m'expliquer  ::)

Merci pour votre aide.

kamill

Bonjour,

Tu peux utiliser strtok()
ou sscanf()

supercc

Une question relative à la question, tes délimiteurs \A \E \P sont-ils réellement présent dans la chaîne ? Le caractère \ sert parfois à indiquer un caractère spécial c'est le cas ?

Dis nous en plus sur ces caractères délimiteurs stp car s'il n'y en a pas, ou s'il y en a 2 caractères par séparateur strtok risque de ne pas convenir.


SimonGEII

Je peux remplacer mes caractères séparateurs par juste A, E et P si cela peut aider en effet.

J'ai penser à un programme qui fait avancer un pointeur de caractère en caractère tant qu'il ne rencontre pas la lettre A par exemple et les recopie 1 à 1 dans une autre chaine, puis lorsque le pointeur est à la lettre A, il commence une autre chaine de caractère et recopie tous les caractères jusqu'à rencontrer la lettre E, etc...

Est ce que ça peut marcher selon vous ?

hbachetti

En supposant que \A représente deux caractères '\\' et 'A', on peut dire qu'avec strtok()
- le 1er jeton peut être extrait avec comme séparateur '\\' seulement
- le 2è jeton peut être extrait avec comme séparateurs 'A et' '\\'
- le 3è jeton peut être extrait avec comme séparateurs 'E et' '\\'

Code: [Select]
void setup() {
  Serial.begin(115200);
  char s[] = "10010\\AE200\\EP550\\P";
  char *a, *b, *c;
  Serial.println(s);
  a = strtok(s, "\\");
  b = strtok(0, "A\\");
  c = strtok(0, "E\\");
  Serial.println(a);
  Serial.println(b);
  Serial.println(c);
}

void loop() {
/*  
*/

}


Attention, avec strtok() la chaîne s doit être une variable, pas une constante.
D'autre par elle sera modifiée par strtok()
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

supercc

Tu es trop fort hbachetti !

donc si tu as le choix du caractère choisi en un (unique). Par exemple ';' et utilise strok ou la fonction index (qui te retournera l'adresse du premier séparateur) et ensuite tu fais avancer ton pointeur. Tu peux t'en sortir sans aucune copie de caractères je pense.

hbachetti

Attention, strtok() ne fait aucune copie.
La fonction place des '\0' aux emplacements des séparateurs et retourne l'adresse du jeton.

Le problème avec la chaîne "10010\\AE200\\EP550\\P " est qu'il y a deux séparateurs qui se suivent.

Donc il vaut mieux considérer que le 'A' et le '\\' suivant sont des séparateurs pour le deuxième jeton.
Le A sera remplacé par '\0' et le '\\' aussi.

Pareil pour le 3è jeton avec 'E' et '\\'.

Le code suivant ne marcherait pas :

Code: [Select]

  a = strtok(s, "\\A");
  b = strtok(0, "\\E");
  c = strtok(0, "\\P");


Car le 'A' sera dans le deuxième jeton.

Mais effectivement tu as raison, on peut faire avancer le pointeur :

Code: [Select]

void setup() {
  Serial.begin(115200);
  char s[] = "10010\\AE200\\EP550\\P";
  char *a, *b, *c;
  Serial.println(s);
  a = strtok(s, "\\");
  b = strtok(0, "\\");
  c = strtok(0, "\\");
  Serial.println(a);
  Serial.println(b+1);
  Serial.println(c+1);
}

void loop() {
/* 
*/

}
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

dbrion06

J'ai testé sur PC quelque chose de légèrement différent (l'anti slash est abominable, car génère des ambiguites)
Code: [Select]

$ cat troncon.cpp &&  g++ troncon.cpp && ./a.exe
#ifndef Arduino
#include <stdio.h>
#include <string.h>
#endif
char tout[]="10010\\AE200\\EP550\\P";
char copie[80]; // copie contiendra une copie de 3 chaines terminees par des \0;
char * tete, * milieu, * queue;
int main() {
 for (int i=0; i < strlen(tout) ; i++) copie[i] = tout[i];
 int etat = 0;
 tete = copie;
 for (int i = 0; i <  strlen(tout); i++ ) {

   if ('\\' == copie[i]) {
    copie[i] = 0; // j'ai tronconné
    etat = etat+1;
    if (etat == 1) milieu = tete + 1 + i;
    if (etat == 2) queue = tete + 1 + i;
    if ( 2 == etat) break; // on s'arrete, car on a coupe en 3, comme prévu
   }
 }
#ifndef Arduino
   printf(" tete :%s milieu %s queue %s\n", tete, milieu, queue);
 return 0;
#endif
}
 tete :10010 milieu AE200 queue EP550\P



SimonGEII

Bonjour à tous,

J'ai pu essayer la première solution de hbachetti et elle marche parfaitement.
J'ai juste remplacer les séparations par des lettres seules (A, E et P).

Merci à tous pour votre aide !


Go Up