Forum Programmation.c manipuler fichier binaire

Posté par  .
Étiquettes : aucune
0
4
oct.
2005
voilà :
fichier binaire :

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

apres traitement :

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 .
2- lire le tag suivant '30' .
3- lire le tag suivant INDIC
4- lire le length de l'information :
si INDIC est 81 le length de l'information est sur 1 octet, 82 --> 2octet, 83 -->3octet, 84 -->4 octet.
si non INDIC = length de l'information (dernière ligne dans l'exemple).
NB : le contenu de length est en hexadecmal .

voilà ou je suis :

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char argv) {
FILE *infile;
FILE *outfile;
char buf[256]; // buffer de lecture
static const char sequence[4] = {0x81,0x82,0x83,0x84};
char header[4]; // header
unsigned char nb;
unsigned char step;
unsigned char tag[2];
unsigned long nbcdrall=0;
int i,offset=24,nbcdrerr=0;
unsigned char name;

if ((infile = fopen(argv[1], "rb")) == NULL)
{
fprintf(stderr, "Pb ouverture infile !n");
return(EXIT_FAILURE);
}
if((name = strdup(argv[1])) == NULL)
{
fprintf(stderr,"Pb avec strdup !n");
return(EXIT_FAILURE);
}
if((outfile = fopen(strcat(argv[1],".NEW"),"wb")) == NULL)
{
fprintf(stderr, "Pb ouverture outfile !n");
fclose(infile);
return(EXIT_FAILURE);
}
while (fread(header, 1, 4, infile) > 0)
{
if(!fread(tag, 1, 2, infile)) // read tag '30' and cdt
{
fprintf(stderr,"fread tag Failure !n");
return(EXIT_FAILURE);
}

if((unsigned char)tag[1] == (unsigned char)sequence[0])
{
step='1';
}
else if((unsigned char)tag[1] == (unsigned char)sequence[1])
{
step='2';
}
else if((unsigned char)tag[1] == (unsigned char)sequence[2])
{
step='3';
}
else if((unsigned char)tag[1] == (unsigned char)sequence[3])
{
step='4';
}
else
step='0';

/*
switch (((unsigned char)tag[1]))
{
case ((unsigned char)sequence[0]):step=1;break;
case ((unsigned char)sequence[1]):step=2;break;
case ((unsigned char)sequence[2]):step=3;break;
case ((unsigned char)sequence[3]):step=4;break;
case default:step=0;
}
/*
if(!fread(&nb, 1, step, infile))
{
fclose(infile);
fclose(outfile);
fprintf(stderr, "Pb lecture infile !n");
return(EXIT_FAILURE);
}
if(fread(buf, 1, nb, infile) != (unsigned int) nb)
{
fclose(infile);
fclose(outfile);
fprintf(stderr, "Pb lecture infile !n");
return(EXIT_FAILURE);
}

if((fwrite(tag, 1, 1, outfile)==0)|| (fwrite(buf, 1, nb , outfile)==0))
{
fprintf(stderr,"fwrite failure !n");
return(EXIT_FAILURE);
}
}
if(rename(argv[1],name)!=0)
{
fprintf(stderr,"rename failure !n");
return(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}


mon problème c'est que je n'arrive pas à avoir le bloc "nb"
quand je fais :
si step est superieur à 1 alors :

fread(&nb, 1, step, infile)

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

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
  • # nb est un octet

    Posté par  . Évalué à 4.

    nb est un char donc tu peux pas lire 3 octets dedans, il faut que tu gères l'offset toi-même.

    le paramètre "step" que tu passes à fread ne sert à rien ici. regarde la valeur de retour pour voir combien d'octets il a lu (1 seul normalement).

    sinon pour connaître la valeur du step t'es pas obligé de faire tes 4 if (encore heureux qu'il y ait pas trop de cas), tu peux utiliser un masque pour prendre seulement le poids faible. tu fais step=step&0x0F;
    • [^] # Re: nb est un octet

      Posté par  (site web personnel) . Évalué à 3.

      le paramètre "step" que tu passes à fread ne sert à rien ici. regarde la valeur de retour pour voir combien d'octets il a lu (1 seul normalement).

      Hélas non. Si step est supérieur à un, fread va lire step*1 (le deuxième argument) octets et ranger tout ça à l'adresse '&nb'. Comme nb est un char, il va yavoir écrasement mémoire. Par contre, ensuite, losqu'on manipule nb, on ne vois que le premier octet, c'est normal, mais plusieurs ont été lus.

      Donc, il faut remplacer nb par un buffer de char suffisament grand (genre char buff[5]), en vérifiant que step est toujours inférieur à la taille de ce tableau. Puis int lu = fread(buff, sizeof(char), step, infile);.
      Noter l'absence de '&' devant buff.

      Maintenant, j'ai pas bien compris le but de cette ligne. Je ne peux donc pas aider plus.
  • # Commentaire complètement inutile

    Posté par  . Évalué à 3.

    Tiens, du BER-TLV :-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.