Je suis en train de faire un convertisseur d'un format de fichier binaire vers ascii, et je dois lire un float codé sur 2 bytes.
J'ai donc le code suivant:
size=2;
ptr=(short int *)malloc(size);
fread(ptr,(size_t)size,1,data_file);
printf("%02X ",*((short int *)ptr));
free(ptr);
Avec prt un pointeur sur void.
Lorsque j'édite mon fichier avec khexedit, cela commence comme ceci:
47d0 63e8 6fa0 43e8 45dc 6fa0 ...
Et mon programme m'affiche ces mêmes lignes de la façon suivante:
FFFFD047 FFFFE863 FFFFA06F FFFFE843 FFFFDC45 FFFFA06F ...
Evidement, lorsque j'essaye d'utiliser ce que je vient de lire pour calculer mon float dans la représentation du fichier binaire, je calcule nimporte quoi...
Donc, comment cela se fait-il que mes deux octets soient inversés lors de ma lecture par rapport a khexedit? Et d'ou viennent des FFFF??
Merci pour toute aide pour éclairer ma lanterne!
Mathias
# un petit endien .. nagawika ...
Posté par ecid . Évalué à 2.
Pour l'inversion, c' est probablement dû au big endian/ little
endian (prise en compte d'abord des octects de poids faible ou de poid fort). Utilise les routines qui permettent de convertir en format "réseau" (man byteorder pour plus d'infos)
[^] # Re: un petit endien .. nagawika ...
Posté par Mathias Bavay (site web personnel) . Évalué à 2.
Mais effectivement, un coup de byteorder et ça repart ! (et les FFFF de tête n'y sont plus).
Merci!
Mathias
[^] # Re: un petit endien .. nagawika ...
Posté par lolop (site web personnel) . Évalué à 2.
printf("%02X ",*((short int *)ptr));
%X c'est destiné à afficher, sous forme hexa, des entiers non signés, et là tu donne un entier court signé.
http://www.opengroup.org/onlinepubs/007908799/xsh/fprintf.ht(...)
Il faudrais que tu passes d'entier court en entier en le spécifiant. Par exemple:
short v ;
assert(sizeof(v)==2) ; // petit controle au cas ou
fread(&v,sizeof(v),1,data_file);
printf("%02X ",(unsigned int)v);
Je ne sais plus comment il joue avec le bit de poids fort lorsqu'il passe d'un signé à un non-signé plus long, mais tu peux éventuellement forcer les bits qui ne te concernent pas à zéro: unsigned int uv = (unsigned int)0x00FFFF & (unsigned int)v ;
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: un petit endien .. nagawika ...
Posté par alf . Évalué à 1.
En C, les conversions se font toujours en essayant de préserver la valeur. Si la valeur de départ "tient" dans le type d'arrivée, alors elle est conservée telle quelle. Sinon, ça dépend... Dans le cas d'une conversion vers un type non signé, la conversion se fait modulo (le nombre maximal représentable par ce type) + 1 (i.e. UINT_MAX +1 dans le cas d'unsigned int).
Donc, si la valeur de v est négative, la conversion en unsigned int se fera avec un changement de valeur modulo UINT_MAX +1. Sinon, comme on a par ailleurs SHORT_MAX <= INT_MAX <= UINT_MAX, la valeur après conversion sera identique. Pas besoin de jouer avec les opérateurs binaires...
En passant, il sert à quoi ton assert ?
# Commentaires
Posté par alf . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.