manupiler un fichier binaire

manupiler un fichier binaire - C - Programmation

Marsh Posté le 04-10-2005 à 11:52:17    

bonjour,
j'ai fait un programme qui fait se qui suit :
Fichier binaire :

Citation :


   A1 A2 A3 A4 30 81 03 B1 B2 B3
   A1 A2 A3 A4 30 82 00 04 B1 B2 B3 B4
   A1 A2 A3 A4 30 83 00 00 03 B1 B2 B3 B4 B5
   A1 A2 A3 A4 30 84 00 00 00 04 B1 B2 B3 B4 B5
   A1 A2 A3 A4 30 07 B1 B2 B3 B4 B5 B6 B7


resultat :

Citation :


   30 81 03 B1 B2 B3
   30 82 00 04 B1 B2 B3 B4
   30 83 00 00 03 B1 B2 B3 B4 B5
   30 84 00 00 00 04 B1 B2 B3 B4 B5
   30 07 B1 B2 B3 B4 B5 B6 B7


 
1- supprimer les 4 premier octets (couleur orange).
2- lire le tag suivant '30' (couleur noir).
3- lire le tag suivant INDIC (couleur rouge)
4- lire le length de l'information :
  si INDIC est 81 le length de l'information (couleur vert) est sur 1 octet, 82 --> 2octet, 83 -->3octet, 84 -->4 octet.
    si non INDIC = length de l'information (dernière ligne dans l'exemple).
voilà ou je suis :

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main(int argc, char ** argv) {
  5. FILE *infile;
  6. FILE *outfile;
  7. char buf[256]; // buffer de lecture
  8. static const char sequence[4] = {0x81,0x82,0x83,0x84};
  9. char header[4]; // header
  10. unsigned char nb;
  11. unsigned char step;
  12. unsigned char tag[2];
  13. unsigned long nbcdrall=0;
  14. int i,offset=24,nbcdrerr=0;
  15. unsigned char *name;
  16.    if ((infile = fopen(argv[1], "rb" )) == NULL)
  17.      {
  18.        fprintf(stderr, "Pb ouverture infile !\n" );
  19.        return(EXIT_FAILURE);
  20.      }
  21.    if((name = strdup(argv[1])) == NULL)
  22.      {
  23.        fprintf(stderr,"Pb avec strdup !\n" );
  24.        return(EXIT_FAILURE);
  25.      }
  26.    if((outfile = fopen(strcat(argv[1],".NEW" ),"wb" )) == NULL)
  27.      {
  28.        fprintf(stderr, "Pb ouverture outfile !\n" );
  29.        fclose(infile);
  30.        return(EXIT_FAILURE);
  31.      }
  32.    while (fread(header, 1, 4, infile) > 0)
  33.      {
  34.        if(!fread(tag, 1, 2, infile)) //  read tag '30' and cdt
  35.         {
  36.           fprintf(stderr,"fread tag Failure !\n" );
  37.           return(EXIT_FAILURE);
  38.         }
  39.      if((unsigned char)tag[1] == (unsigned char)sequence[0])
  40.          {
  41.            step='1';
  42.          }
  43.      else if((unsigned char)tag[1] == (unsigned char)sequence[1])
  44.          {
  45.            step='2';
  46.          }
  47.      else if((unsigned char)tag[1] == (unsigned char)sequence[2])
  48.          {
  49.            step='3';
  50.          }
  51.      else if((unsigned char)tag[1] == (unsigned char)sequence[3])
  52.         {
  53.           step='4';
  54.         }
  55.      else
  56.         step='0';
  57.      /*
  58.      switch (((unsigned char)tag[1]))
  59.          {
  60.            case ((unsigned char)sequence[0]):step=1;break;
  61.            case ((unsigned char)sequence[1]):step=2;break;
  62.            case ((unsigned char)sequence[2]):step=3;break;
  63.            case ((unsigned char)sequence[3]):step=4;break;
  64.            case default:step=0;
  65.          }
  66.      */
  67.       if(!fread(&nb, 1, step, infile))
  68.          {
  69.            fclose(infile);
  70.            fclose(outfile);
  71.            fprintf(stderr, "Pb lecture infile !\n" );
  72.            return(EXIT_FAILURE);
  73.          }
  74.       if(fread(buf, 1, nb, infile) != (unsigned int) nb)
  75.          {
  76.             fclose(infile);
  77.             fclose(outfile);
  78.             fprintf(stderr, "Pb lecture infile !\n" );
  79.             return(EXIT_FAILURE);
  80.           }
  81.       if((fwrite(tag, 1, 1, outfile)==0)|| (fwrite(buf, 1, nb , outfile)==0))
  82.           {
  83.             fprintf(stderr,"fwrite failure !\n" );
  84.             return(EXIT_FAILURE);
  85.           }
  86.       }
  87.   if(rename(argv[1],name)!=0)
  88.    {
  89.     fprintf(stderr,"rename failure !\n" );
  90.     return(EXIT_FAILURE);
  91.    }
  92.    return(EXIT_SUCCESS);
  93. }


 
si qlq à une meilleur idées ou un code plus simple je suis preneur !
 
Merci
 
 
 
 
 

Reply

Marsh Posté le 04-10-2005 à 11:52:17   

Reply

Marsh Posté le 04-10-2005 à 17:27:53    

demo2000 a écrit :

si qlq à une meilleur idées ou un code plus simple je suis preneur !
 
Merci


 
Après un premier regard rapide, voici mes remarques
1) ton code en commentaire "switch(...)" pour assigner le "step" en fonction de la valeur de "INDIC" ne peut pas fonctionner. Chaque élément de "case" doit impérativement être une constante et ne peut pas être une variable. C'est parce que le compilo remplace le bloc "switch(...)" par des "goto" (tu remarqueras d'ailleurs que le "case" se termine toujours par des ":" représentatifs des labels)
 
2) "case default" n'existe pas (heureusement que c'est en commentaire)
 
3) je ne suis pas certain que step='1' ou step='2' corresponde à ce que tu veux. Il ne faut pas confondre la valeur "2" (notée 2) et le caractère "2" (noté '2')
 
4) plutôt que de faire plein de "if" pour assigner "step" en fonction de "indic", moi j'aurais créé une structure de correspondance et fait un balayage de recherche.
 
Exemple

Code :
  1. typedef struct {
  2.     char indic;
  3.     unsigned char step;
  4. }t_sequence;
  5. ...
  6. ...
  7. main()
  8. {
  9.     ....
  10.     // Déclaration du tableau des séquences cherchées et du pointeur pour le balayer
  11.     t_sequence tabSequence[]={
  12.         {0x81, 1},
  13.         {0x82, 2],
  14.         {0x83, 3},
  15.         {0x84, 4},
  16.         {0x00, 0}
  17.     };
  18.     t_sequence *ptSequence;
  19.     ....
  20.     ....
  21.     // Recherche de la séquence sur "tag[1]"
  22.     step=0;
  23.     for (ptSequence=tabSequence; ptSequence->indic != 0; ptSequence++)
  24.     {
  25.          if (ptSequence->indic == tag[1])
  26.          {
  27.               step=ptSequence->step;
  28.               break;
  29.           }
  30.      }
  31.      // Ici, "step" vaut la bonne valeur en fonction de "INDIC"
  32.      ...
  33. }


 
Cela permet de faire évoluer ton programme plus facilement. Par exemple, si demain il y a la valeur "0x85" qui vient se rajouter dans les valeurs possibles, tu n'as qu'une ligne à rajouter dans mon exemple alors qu'il te faut programmer tout un bloc de test en plus dans ton programme.
 
Pour le reste, j'ai pas examiné en détail mais ça semble correct.

Reply

Marsh Posté le 04-10-2005 à 18:50:55    

merci Sve@r pour tes remarques.
mon problème c'est que je n'arrive pas à avoir le bloc "nb"
quand je fais :
si step >= 2 alors :

Code :
  1. fread(&nb, 1, step, infile)


il lis seulement le premier octet.
c.a.d:
Fichier binaire :

Citation :


   A1 A2 A3 A4 30 81 03 B1 B2 B3  // nb=03 --> OK
   A1 A2 A3 A4 30 82 00 04 B1 B2 B3 B4 //nb=00 au lieu 0004
   A1 A2 A3 A4 30 83 00 00 03 B1 B2 B3 B4 B5 //nb=00 au lieu de 000003


le length (en vert) est en Hexadecimal.
 
Merci encore pour votre aide.
 
 
 

Reply

Marsh Posté le 04-10-2005 à 19:59:38    

C'est normal, nb est un unsigned char.

Reply

Sujets relatifs:

Leave a Replay

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