insérer des octets en debut de tableau

insérer des octets en debut de tableau - C - Programmation

Marsh Posté le 22-11-2006 à 15:49:35    

coucou,
voila mon problème.
j'ai deux fonctions : l'une renvoie un pointeur sur un tableau  d'octet et sa longueur
l'autre prend en parametre le tableau modifié comme suit:
XX|XX|Tableau
 ou XX|XX  représente la longeur des donnees sur 2 octets.
 
Jusqu'a présent , on déclare un tableau de 1024, recopie de la réponse de la fonc 1, décallée de 2 octets dans le tableau de 1024 puis renseignement des 2 premiers octets.
c'est pas propre et surtout ca prend 1024 octets pour un tableau intermédiaire qui n'a pas lieu d'être.
connaissez vous une technique en C permettant à partir d'un pointeur sur une suite d'octets, de décaller celui-ci de 2 octets sur la droite sans utiliser de memoire intermédiaire? (il y a aussi un pb de débordement de 2  octets à prendre en compte :s )
 

Reply

Marsh Posté le 22-11-2006 à 15:49:35   

Reply

Marsh Posté le 22-11-2006 à 15:52:09    

euh, sauf si j'ai mal compris, pointeur + 2 ?

 

Tu conserves le pointeur original pour pouvoir faire une désallocation propre à la fin (et garder l'adresse du début du tableau surtout), et sur tes fonctions de remplissage, tu décales comme tu veux en ajoutant au pointeur la longueur de décalage voulue (un pointeur c'est juste une variable qui contient une adresse)

 

edit : je viens de comprendre. Si le tableau est assez grand pour ajouter les deux bytes, utilises memmove(), pas besoin de passer par un tableau intermédiaire. Et si le tableau est pas assez grand, utilise realloc(), ce qui suppose que ton tableau est dynamiquement alloué


Message édité par Elmoricq le 22-11-2006 à 15:56:02
Reply

Marsh Posté le 22-11-2006 à 16:02:09    

merci je vais essayer avec ces fonctions

Reply

Marsh Posté le 22-11-2006 à 16:31:08    

c'est un peu la prise de tête. Tu as des bibliothèques simple comme la glib (http://www.gtk.org) qui ont des petits type GArray/GByteArray/GPtrArray plus facile à manipuler

Reply

Marsh Posté le 22-11-2006 à 16:37:12    

salut j'ai fait un truc dans ce style

Code :
  1. BuftoSend = realloc(reponse,LentoSend+2);
  2. memmove(BuftoSend,&BuftoSend[2],LentoSend);
  3. for (i=LentoSend, i>=0, i--)
  4.    BuftoSend[i+2]=BuftoSend[i];
  5. BuftoSend[0]  = (LentoSend & 0xFF00) / 0x100;
  6. BuftoSend[1]  = LentoSend & 0x00FF;
  7. LentoSend  = LentoSend + 2;


bon ca marche pas, sans doute le memmove ca me parait un peu simple comme manip'

Reply

Marsh Posté le 22-11-2006 à 16:39:55    

je suis sur un terminal bancaire, l'ajout de lib c'est tendu.
je vais tester avec une bonne vielle boucle for bien lente pour remplacer le memmove

Message cité 1 fois
Message édité par djobidjoba le 22-11-2006 à 16:40:42
Reply

Marsh Posté le 22-11-2006 à 16:42:10    

djobidjoba a écrit :


j'ai deux fonctions : l'une renvoie un pointeur sur un tableau  d'octet et sa longueur
l'autre prend en parametre le tableau modifié comme suit:
XX|XX|Tableau
 ou XX|XX  représente la longeur des donnees sur 2 octets.
 
Jusqu'a présent , on déclare un tableau de 1024, recopie de la réponse de la fonc 1, décallée de 2 octets dans le tableau de 1024 puis renseignement des 2 premiers octets.
c'est pas propre et surtout ca prend 1024 octets pour un tableau intermédiaire qui n'a pas lieu d'être.
connaissez vous une technique en C permettant à partir d'un pointeur sur une suite d'octets, de décaller celui-ci de 2 octets sur la droite sans utiliser de memoire intermédiaire? (il y a aussi un pb de débordement de 2  octets à prendre en compte :s )


Si il est dimensionné correctement, memmove().
 
Mais si tu veux bien faire, il vaut mieux allouer un bloc de taille raisonnable (genre 80% des cas) réserver la place au début pour la taille, quitte à réallouer le bloc (et penser à modifier la taille) si il est trop petit dans les 20% de cas restant... Encore une utilisation de la règle classique des 80/20...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-11-2006 à 16:49:05    

djobidjoba a écrit :

je suis sur un terminal bancaire, l'ajout de lib c'est tendu.
je vais tester avec une bonne vielle boucle for bien lente pour remplacer le memmove


bah alors commence par vérifier le retour de realloc ...

Reply

Marsh Posté le 22-11-2006 à 16:55:49    

djobidjoba a écrit :

salut j'ai fait un truc dans ce style

Code :
  1. BuftoSend = realloc(reponse,LentoSend+2);
  2. memmove(BuftoSend,&BuftoSend[2],LentoSend);
  3. for (i=LentoSend, i>=0, i--)
  4.    BuftoSend[i+2]=BuftoSend[i];
  5. BuftoSend[0]  = (LentoSend & 0xFF00) / 0x100;
  6. BuftoSend[1]  = LentoSend & 0x00FF;
  7. LentoSend  = LentoSend + 2;


bon ca marche pas, sans doute le memmove ca me parait un peu simple comme manip'

 

Euh, l'est zarb ton code, tu es sûr de toi sur ce coup ?
Parce que là tu demandes à memmove() de copier LentoSend bytes, de &BuftoSend[2], vers BuftoSend.

 

Je crois que tu t'es trompé. Surtout que si LentoSend est la longueur de ton tableau, la boucle qui suit aussi est fausse.

 


edit : pour t'aider, la manpage sur memmove() :

 

Standard C Library Functions                           memory(3C)

 

NAME
     memory, memccpy, memchr, memcmp, memcpy, memmove,  memset  -
     memory operations

 

SYNOPSIS
     #include <string.h>

 

    void *memmove(void *s1, const void *s2, size_t n);

 

DESCRIPTION
     These functions operate as efficiently as possible on memory
     areas (arrays of bytes bounded by a count, not terminated by
     a null character).  They do not check for  the  overflow  of
     any receiving memory area.

 

    The memmove() function copies n bytes from memory  areas  s2
     to s1.  Copying between objects that overlap will take place
     correctly. It returns s1.

 

SEE ALSO
     string(3C), attributes(5)

 


(je n'ai gardé que les parties concernant memmove() )


Message édité par Elmoricq le 22-11-2006 à 16:58:14
Reply

Marsh Posté le 22-11-2006 à 17:17:10    

memmove ne détruit rien :
- si src et dst ne se chevauchent pas
- si src < dst et dst < src + n

Reply

Marsh Posté le 22-11-2006 à 17:17:10   

Reply

Marsh Posté le 22-11-2006 à 17:21:24    

djobidjoba a écrit :

salut j'ai fait un truc dans ce style

Code :
  1. BuftoSend = realloc(reponse,LentoSend+2);
  2. memmove(BuftoSend,&BuftoSend[2],LentoSend);
  3. for (i=LentoSend, i>=0, i--)
  4.    BuftoSend[i+2]=BuftoSend[i];
  5. BuftoSend[0]  = (LentoSend & 0xFF00) / 0x100;
  6. BuftoSend[1]  = LentoSend & 0x00FF;
  7. LentoSend  = LentoSend + 2;




 [:arrakys]

Code :
  1. #include "ed/inc/sys.h"
  2. int main (void)
  3. {
  4.    size_t LentoSend = 16;
  5.    unsigned char *BuftoSend = malloc (LentoSend);
  6.    strncpy (BuftoSend, "Hello world", LentoSend);
  7.    BuftoSend = realloc (BuftoSend, LentoSend + 2);
  8.    memmove (BuftoSend + 2, BuftoSend, LentoSend);
  9.    LentoSend += 2;
  10.    BuftoSend[0] = (LentoSend >> (8 * 1)) & 0xFF; /* MSB */
  11.    BuftoSend[1] = (LentoSend >> (8 * 0)) & 0xFF;
  12.    SYS_dump (BuftoSend, LentoSend);
  13.    return 0;
  14. }



003D24E8 00 12 48 65 6C 6C 6F 20 77 6F 72 6C 64 00 00 00  '..Hello world...'
003D24F8 00 00                                            '..'

 

Press ENTER to continue.


Mais je recommande plutôt ceci :

Code :
  1. #include "ed/inc/sys.h"
  2. int main (void)
  3. {
  4.    size_t LentoSend = 16;
  5.    unsigned char *BuftoSend = malloc (LentoSend + 2);
  6.    strncpy (BuftoSend + 2, "Hello world", LentoSend);
  7.    BuftoSend[0] = (LentoSend >> (8 * 1)) & 0xFF; /* MSB */
  8.    BuftoSend[1] = (LentoSend >> (8 * 0)) & 0xFF;
  9.    SYS_dump (BuftoSend, LentoSend);
  10.    return 0;
  11. }


C'est quand même carrément moins tordu...


003D24E8 00 10 48 65 6C 6C 6F 20 77 6F 72 6C 64 00 00 00  '..Hello world...'

 

Press ENTER to continue.


C'est une technique classique et portable.

 

Le code manquant est là :

 

http://mapage.noos.fr/emdel/clib.htm

Message cité 1 fois
Message édité par Emmanuel Delahaye le 22-11-2006 à 17:24:17

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-11-2006 à 01:57:41    

merci pour votre aide ! =)

Reply

Marsh Posté le 26-11-2006 à 02:07:05    

Emmanuel Delahaye a écrit :

[:arrakys]  

Code :
  1. #include "ed/inc/sys.h"
  2. int main (void)
  3. {
  4.    size_t LentoSend = 16;
  5.    unsigned char *BuftoSend = malloc (LentoSend);
  6.    strncpy (BuftoSend, "Hello world", LentoSend);
  7.    BuftoSend = realloc (BuftoSend, LentoSend + 2);
  8.    memmove (BuftoSend + 2, BuftoSend, LentoSend);
  9.    LentoSend += 2;
  10.    BuftoSend[0] = (LentoSend >> (8 * 1)) & 0xFF; /* MSB */
  11.    BuftoSend[1] = (LentoSend >> (8 * 0)) & 0xFF;
  12.    SYS_dump (BuftoSend, LentoSend);
  13.    return 0;
  14. }



003D24E8 00 12 48 65 6C 6C 6F 20 77 6F 72 6C 64 00 00 00  '..Hello world...'
003D24F8 00 00                                            '..'
 
Press ENTER to continue.


Mais je recommande plutôt ceci :  

Code :
  1. #include "ed/inc/sys.h"
  2. int main (void)
  3. {
  4.    size_t LentoSend = 16;
  5.    unsigned char *BuftoSend = malloc (LentoSend + 2);
  6.    strncpy (BuftoSend + 2, "Hello world", LentoSend);
  7.    BuftoSend[0] = (LentoSend >> (8 * 1)) & 0xFF; /* MSB */
  8.    BuftoSend[1] = (LentoSend >> (8 * 0)) & 0xFF;
  9.    SYS_dump (BuftoSend, LentoSend);
  10.    return 0;
  11. }


C'est quand même carrément moins tordu...


003D24E8 00 10 48 65 6C 6C 6F 20 77 6F 72 6C 64 00 00 00  '..Hello world...'
 
Press ENTER to continue.


C'est une technique classique et portable.
 
Le code manquant est là :  
 
http://mapage.noos.fr/emdel/clib.htm


 
Question bète, pourquoi 8 et pas CHAR_BIT ?

Reply

Marsh Posté le 26-11-2006 à 12:27:35    

0x90 a écrit :

Question bète, pourquoi 8 et pas CHAR_BIT ?


Parce que ce qu'on veut ici, c'est très précisément 8 et non CHAR_BIT. Les données lues d'un flux font 8 bits, même si CHAR_BIT vaut 9, 16 ou 32. Ne pas confondre le format des données du C (strictement interne) et le format des données externes qui ne dépend pas du C. Dans un flux, quelque soit la machine, les données auront 8 bits significatifs de large. Toute la politique d'inter-fonctionnement des machines (fichiers, bases de données, réseaux etc.) est basé sur ce principe. Et ça n'a rien à voir avec le langage C.

 

Message cité 1 fois
Message édité par Emmanuel Delahaye le 26-11-2006 à 12:30:26

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-11-2006 à 14:31:34    

Emmanuel Delahaye a écrit :

Parce que ce qu'on veut ici, c'est très précisément 8 et non CHAR_BIT. Les données lues d'un flux font 8 bits, même si CHAR_BIT vaut 9, 16 ou 32. Ne pas confondre le format des données du C (strictement interne) et le format des données externes qui ne dépend pas du C. Dans un flux, quelque soit la machine, les données auront 8 bits significatifs de large. Toute la politique d'inter-fonctionnement des machines (fichiers, bases de données, réseaux etc.) est basé sur ce principe. Et ça n'a rien à voir avec le langage C.


 
Merci :jap:

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed