Decomposition de buffer

Résolu
Signaler
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
-
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
-
salut,

j'aimerais de l'aide ou sinon au moins des précisions si possible sur un petit bout de code SVP.

Voila mon pb : je recupére une trame dans un buffer défini ainsi BYTE buffer[4000];
ma trame est composée comme ceci : STX-DATA-ETX (en tres gros)
STX et ETX sont de l'hexa correspondant a 0x02 et 0x03 respectivement.
mes données sont une suite de caractére a decomposer aussi on va dire 5caractere pour le nom suivi de 10 pr le prenom (pr exemple)

voila je ne sais pas trop comment decomposer ma trame et retirer les STX ETX et ensuite decomposer ma chaine de caracteres qui est en hexa
pr les stocker dans des variables comme cela: char prenom [10]; char nom[5];

si mon buffer originel était une chaine de caractere j'aurais pu faire : strncpy_s( nom, buffer , 5);
mais comme la mon buffer est une suite d'octets je ne sais pas comment faire l'equivalent ...

pourriez vous m'aider ou du moins me guider SVP ! merci d'avance.

 

51 réponses

Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
ouais c'est normal, strcmp bosse sur des chaines, pas des caractères simples.

remplace
char MsgTyp[1+1] = "";   // au fait 1+1 ca fait 2
    memcpy(MsgTyp, lpBuffer, 1);
    MsgTyp[1] = '\0';
    if(strcmp(MsgTyp,ENQ) == 0)

par

char MsgTyp = lpBuffer[0];   // là tu attribue la valeur du premier octet de lpBuffer à ta variable
if (MsgTyp == ENQ)            // là tu vérifies que la valeur de la variable est bien égale à ENQ

tu gagnes un octet (chouette!) et tu te simplifies la lecture. et en plus ça doit marcher ce qui n'est pas négligeable.

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
heu...dois je comprendre par le manque de reponses que mon sujet n'est aps clair ou juste que personne en sait trop repondre ?

 
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
essaye :

void * memcpy ( void * destination, const void * source, size_t num );

Neo_Fr
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
oki merci , je vais essayer des que possible et je valide al réponse si ca passe bien !!!
 
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
tu bosse avec du serie RS232 ?

Solution possible (que je n'aime pas, en C++ avec un parser c'est plus joli) :

char prenom [11]; char nom[6];

BYTE buffer[4000];




// buffer+1 pour skipper le STX
memcpy(nom, buffer+1, 5);
nom[5] = '\0';

// buffer+6 pour skipper le STX plus le nom
memcpy(prenom , buffer+6, 10);
prenom [10] = '\0';

:D
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
salut,

le problème Keniiyk c'est que 5 et 10 lettres étaient des exemples. je suppose que ça doit être variable.

LaTatadu91 > il faut savoir qu'un char est codé sur un octet exactement comme un BYTE.
ensuite, ta chaine n'est ni en hexa ni en décimal ni en cacahuètes, c'est une liste de bits à 0 ou 1. après tu la lis comme tu veux.
buffer[0] est STX que tu peux stocker dans un char si besoin, de même que ETX (je ne sais pas s'il est forcément à l'adresse buffer[3999] ou bien si le texte fait par exemple 20 caractères, le ETX est à buffer[20], à vérifier donc)
pour le reste tu peux faire une copie avec strcpy.

Loki
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
pour ce qui est de trier les différents champs de la partie DATA, tu as deux possibilités :

    - soit pour chaque champ il n'y a qu'un seul mot, dans ce cas c'est simple : tu te places au début à buffer[1] tu récupères le mot avec sscanf(), ensuite tu dégages jusqu'au prochain espace avec strstr() etc... pour chaque champ.

    - soit tu peux avoir des noms comme (Jean-Baptiste) "de la fraise tagada". à ce moment là c'est plus ch****. il faudrait que tu aies un caractère spécial comme ';' dont tu te sers pour séparer tes champs, encore faut-il pouvoir les insérer à la création de la trame...
si tu peux, alors il faut lire chaque caractère et non plus des mots (car sscanf termine la lecture d'une chaine à chaque espace rencontré), jusqu'à tomber sur ';'.

voilà j'espère que ça répond à tes questions.

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
en fait mon buffer de données sera toujours composé ainsi : STX-DATA-ETX ce qui n'est pas fixe c'est : la partie DATA.
Mais les 2 premiers caracteres de DATA m'indiqueront quel type de données je dois decomposer!
ainsi suivant le type de données je peux decomposer DATA avec pr mon exmple : 5caracteres pr le nom et 10 pr le prenom...
par contre je peux aussi avoir d'autre types de messages : ENQ et ACK donc
1/ je dois definir quel type de message m'arrive avec le premier octet de ma trame (ENQ,ACK,STX)
2/suivant le type de message je dois agir :
                         - Si c'est ENQ --> envoi d'un ACK
                         - Si c'est STX --> decomposition de DATA dans mes variables (memcpy)....

donc la solution de keniiyk me semble pas mal , car effectivement pr chaque chaine de caractere de DATA je sais de combien de caractere elle se compose.

il me reste juste a identifier les types ENQ ,STX ...

en faisant cela alors :
memcpy(MsgTyp, buffer, 1);
if (strcmp(MsgTyp,STX) ==0)
....
if (strcmp(MsgTyp,ENQ) ==0)
....

en declarant STX et ENQ comme ceci :
char  STX  =  0x02;           // start transmission marker
char  ETX  =  0x03;           // end transmission marker
char     ACK  =  0x06;                // Acquittement du message
char     ENQ  =  0x05;           // Enquiry

ca vous parait correct ?

en tout cas merci pr votre aide!!!

 
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
ah ok, j'avais pas vu ça comme ça. dans ce cas en effet.

y a t'il une différence entre memcpy(MsgTyp, buffer, 1); et MsgTyp = buffer[0] ?
de même qu'entre strcmp(MsgTyp,STX) ==0 et MsgType == STX ?

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
ben a priori a toi de me le dire ...
moi j'aurai tendance a utiliser les memcpy et strcmp mais si tu me dis que c'est equivalent ben oki...
donc ma declaration des STX etc... c'est bon?

 
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
ah bah moi j'y conais rien à tous ces trucs, j'étais venu pour demander quel terreau acheter pour mes bégonias

mais sinon ça a l'air bon : http://www.commentcamarche.net/base/ascii.php3

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
lol nan mais serieux ty connais rien ou t'es un master?
moi je suis un jeune padawan qui cherche a devenir jedi
mais bon le coté obscur me guette....
il faut que je trouve yoda du coup!!!
 
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
bah disons que je suis loin d'être novice, mais encore plus loin d'être un master.
mais pour ce qui est de la déclaration des STX etc... oui, c'est les bon numéros.

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
ecoute je te dis merci...
le coté hexa c'est pas vraiment ce que je prefere ....
j'ai du secher trop de cours LOL

 
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
j'ai ca comme erreur :
error C2664: 'strcmp' : impossible de convertir le paramètre 2 de 'char' en 'const char *'

char MsgTyp[1+1] = "";
    memcpy(MsgTyp, lpBuffer, 1);
    MsgTyp[1] = '\0';
    if(strcmp(MsgTyp,ENQ) == 0)
avec
char     ENQ  =  0x05;   

il veut pas comparer ces 2 param...
 
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
char ENQ[2] = {0x05,'\0'};

'\0' obligatoire si utilisation des methodes style strcmp

sinon if( MsgTyp[0] == ENQ) // avec char     ENQ  =  0x05;   

:D
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
super !!! merci de ton aide !!!

 
Messages postés
286
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
27 décembre 2009
2
de rien.

si tu es tout bon n'oublie pas de valider le topic

Loki
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
oki merci encore a vous deux !!!
et pr le 1+1 c'est une notation que je laisse pr que l'on comprenne bien que le +1 correspond au fin de chaine....

 
Messages postés
968
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
26 avril 2013
1
il me jette avec ca : char MsgTyp = lpBuffer[0];

error C2036: 'LPVOID' : taille inconnue
error C2440: 'initialisation' : impossible de convertir de 'void' en 'char'

par contre c'est bon avec les strcmp et memcpy ...