cs_MrDimanche
Messages postés16Date d'inscriptionmercredi 25 juillet 2007StatutMembreDernière intervention16 avril 2008
-
25 juil. 2007 à 09:03
ctx_man
Messages postés285Date d'inscriptionmardi 28 décembre 2004StatutMembreDernière intervention20 janvier 2013
-
25 juil. 2007 à 11:53
Bonjour, voila ce qui m'amène.
Je dois lire un fichier de données binaire, et le convertir. Mais si j'ai une petite expérience en c, c'est la première fois que je fais ce genre de travail, et je m'embrouille.
Le fichier se trouve generalement en mots de 32 bits, mais pas toujours, et mon programme ne lit que par mots de 32 bits (que je met dans un buffer[]). Mais mon plus gros problème est que un mot dont la valeur est 0bf6752e sort tel que 2e75f60b, soit chaque octet à l'envers.
Ce qui m'amène à mes deux questions : comment faire pour mon programme lise plutôt octets par octets, ou même bit par bit (certaines données sont sur 1 bit), et comment inverser chaque mots pour retrouver la bonne valeur ? Merci pour votre aide, je sais qu'ainsi ce n'est pas très clair, mais je joint le programme que j'ai récupéré, et j'ai bricolé quelques solution, mais ça ne marche pas toujours :
//fonction qui permet d'inverser les octet dans 32 bits, mais ne marche pas toujours
int reverseByte(int buffer)
{
int tamp=0;
tamp=16777216*(buffer-256*(int)(buffer/256));
tamp=tamp+65536*((int)(buffer/256)-(256*(int)(buffer/65536)));
tamp=tamp+256*((int)(buffer/65536)-(256*(int)(buffer/16777216)));
tamp=tamp+(int)(buffer/16777216);
return tamp;
}
int main () {
FILE * pFile;
long lSize;
int * buffer;
size_t result;
int i,n,MainN;
pFile = fopen ( "/Users/nicole/Nemo/nemo_ph1_R00000018_F00000005.dat" , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// allocate memory to contain the whole file:
buffer = (int*) malloc (sizeof(int)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
/* the whole file is now loaded in the memory buffer. */
for(i=0;i<3;i++)
printf("%.8x\n",buffer[i]);
// terminate
//printf("%x\t",(int)(buffer[0])/65536);
fclose (pFile);
buffer[0]=reverseByte(buffer[0]);
printf("The version date : %d\n",buffer[0]);
buffer[1]=reverseByte(buffer[1]);
printf("The size (byte): %d\n",buffer[1]); //cette partie marche, mais par pour chaques mot :s
ctx_man
Messages postés285Date d'inscriptionmardi 28 décembre 2004StatutMembreDernière intervention20 janvier 20133 25 juil. 2007 à 10:37
Petite astuce pour retourner un mot super facilement :
char* FileStream; //On va utiliser un pointer de caractère pour lire
int* Buffer;
Buffer = (int*) malloc (sizeof(int)*lSize);
FileStream = (char*)Buffer; //Faire pointer ton char* sur ton Buffer
result = fread (FileStream,1,lSize,pFile);
Et voila, grace a l'arithmétique des pointeurs, ton entier est écrit a l'envers.
En fait ton problème de retournement via d'ailleur de la je pense.
En gros tu écrit des int et tu lit des char, donc si ta mémoire est en adresse forte = poid faible (little-endian si je me trompe pas ce qui est fort probable) alors la lecture en char va t'inverser les données. Puisque dans ton fichier le poids faible est est l'adresse faible et il va se retrouver à l'adresse faible de ton int, qui en mémoire représente le poid fort. (Je doute fortement de la clareté de mes propos la ...)
Enfin bref, si tu lit des mots de 32 bits, alors lit par block de 32 bits.
result = fread (buffer, 4, lSize / 4, pFile);
Si vraiment c'est pas possible et que mon astuce précitée ne fonctionne pas, alors voici comment on fait un retournement normalement