fread - C - Programmation
Marsh Posté le 28-04-2011 à 16:15:32
Version courte: ton problème se résume à: http://fr.wikipedia.org/wiki/Endianness
Pour savoir si tu as lu 2 octets, regarde le code de retour de fread.
Marsh Posté le 28-04-2011 à 16:22:28
Citation : printf("%d\n",c); // affiche la valeur decimale de l'octet |
Avec printf(), il est recommandé de caster les paramètres (surtout si on utilise %d pour autre chose qu'un int), par exemple :
printf("%d\n", (int)(c)); // affiche la valeur decimale de l'octet |
Marsh Posté le 28-04-2011 à 16:34:14
fread me retourne effectivement 2. Donc a lu deux octets.
Mais pourquoi il m'affiche 32 alors ? comme s'il n'avait lu qu'un seul octet.
J'ai lu la page wikipédia, comment savoir comment mon ordinateur manipule les octets, si c'est en big-endian ou little-endian, pouvez vous m'éclaircir à ce sujet?
J'aimerais vraiment extraire les deux derniers octets de mon fichier, et je ne vois coment pour l'instant
Marsh Posté le 28-04-2011 à 16:35:25
Merci olivthill, j'ai rectifié, mais les affichage c'était seulement pour vérifier les données extraites
Marsh Posté le 28-04-2011 à 16:40:42
Code :
|
Cet appel lit en réalité 2 fois 2 octets. Tu devrais mettre 1 en troisième paramètre.
Marsh Posté le 28-04-2011 à 16:41:49
D'après ce que tu affiches, ton ordinateur est en little endian (tu dois probablement être sous Windows...).
Si tu veux afficher les deux octets, affiche ton contenu octet par octet alors :
Code :
|
Arf, j'ai vu en plus que tu risque d'avoir un stack overflow dans ton programme :
Code :
|
Tu lis 2 entiers de la taille de ta variable i. Or i ne peux contenir qu'un seul entier => stack overflow si tu n'est pas à la fin du fichier.
Citation : Avec printf(), il est recommandé de caster les paramètres (surtout si on utilise %d pour autre chose qu'un int), par exemple : |
Ce n'est pas nécessaire pour les types dont la taille est inférieure ou égale à celle d'un int à cause de la promotion implicite en int dans la partie vararg.
Marsh Posté le 28-04-2011 à 16:51:28
tpierron a écrit : |
[Mode hors sujet on]
Je ne suis pas expert, mais il me semble que l'endianness dépend de l'architecture matérielle et non pas du système d'exploitation. Donc il pourrait aussi bien être sous Linux ! (Non, non, je ne lance pas de troll...)
[Mode hors sujet off]
Marsh Posté le 28-04-2011 à 17:00:08
1.Je remets mon code réctifié, effectivement j'ai fait des fautes de frappe dans le recopiage
Code :
|
et m'affiche
Code :
|
Marsh Posté le 28-04-2011 à 17:00:32
shaoyin a écrit : |
Arf, ce que je voulais surtout dire en fait, c'est que si tu es sous Windows, tu auras une archi little endian derrière.
Marsh Posté le 28-04-2011 à 17:01:11
j'utilise VMWARE, et je travaille avec Ubuntu.
Mais il est lancé à partir de Windows, je ne pense que cela soit considéré comme si je travaillais sous windows?
Marsh Posté le 28-04-2011 à 17:08:26
Mais le probleme, c'est que mon programme je vais l'envoyer à mes profs.
S'ils n'ont pas la même architecture que moi, cela risque de poser probleme dans la lecture de fichier, non ?
Marsh Posté le 28-04-2011 à 18:10:07
rahela a écrit : Mais le probleme, c'est que mon programme je vais l'envoyer à mes profs. |
T'occupe pas de ça pour l'instant. Question bête mais quand même: ton fichier fait bien plus de 2 octets?
Sinon j'ai trouvé ça:
Return Value
The total number of elements successfully read is returned as a size_t object, which is an integral data type.
If this number differs from the count parameter, either an error occured or the End Of File was reached.
You can use either ferror or feof to check whether an error happened or the End-of-File was reached.
-mettre la valeur de retour dans un size_t
-utiliser ferror et feof pour vérifier qu'un erreur est survenu ou qu'on est arrivé à la fin du fichier.
Marsh Posté le 28-04-2011 à 19:15:16
ouioui normalement il y a 5 octets a lire, j'ai reussi à parcourir le fichier octet par octet en appelant 5fois fread(&c,1,1,f); ca ne ma pas posé de probleme...
Marsh Posté le 28-04-2011 à 20:51:42
J'ai compris !!!! il recupere bien deux octets, il recupere 0010 0000 et 0000 0000 , mais comme mon ordi est en little- endian il inverse les deux octets, ce qui donne
0000 0000 0010 0000 et donc c'est pour cela qu'il m'affiche 32 ! tous les 0 avant deviennent insignifiants
Marsh Posté le 28-04-2011 à 20:52:04
ReplyMarsh Posté le 28-04-2011 à 21:43:40
rahela a écrit : donc je dois effectuer une inversions? |
Non, lis ton fichier comme une suite d'octet. De cette manière :
Code :
|
Maintenant si tu veux manipuler (de manière portable) tes deux octets comme un nombre, tu peux écrire :
Code :
|
Cela suppose donc que ton fichier stocke les entiers de plus d'un octet en big endian.
C'est chiant, mais c'est le prix à payer quand on manipule des données binaires.
Edit: le "unsigned" est important dans ce cas, car sinon tu auras une extension du signe pour les valeurs > 127, avec des valeurs complètement fausses si tu essayes de le reconvertir en entier avec des décalages binaires.
Marsh Posté le 28-04-2011 à 23:24:11
Merci, ca marche impec !
une autre question, l'operation pourquoi ( ( (buffer[0]<<8) | buffer[1] ) & 0x1FFF ) ne marche pas ?
si je teste 0x2002 & 0x1FFF, ca marche correctement...
Marsh Posté le 28-04-2011 à 16:11:32
Bonjour !
j'ai un soucis avec la fonction fread, lorsque je lui demande de lire 2octets elle ne m'en lit qu'un seul.
Je lis un fichier binaire.
voici mon code :
mon fichier binaire contient les bits suivants : 0000 1000 0010 0000 0000 0000 (je les espace exprès ici pour mieux voir , dans le fichier ils sont à la suite).
lorsque j'exécute mon programme, j'ai la sortie suivante :
8 est bien la valeur décimale de 0000 1000
mais 32 est la valeur décimale de 0010 0000, donc la fonction n'a lu qu'un octet alors que j'aurai voulu qu'elle me lise 0010 0000 0000 0000 et qu'elle affiche la valeur 8192
Voilà , je m'aide de cette page http://www.aly-abbara.com/utilitai [...] ffres.html pour faire mes conversions car je ne crois pas qu'il existe un symbole pour afficher les nombres binaires.
Voilà, j'espère avoir été assez claire,
je vous remercie d'avance