Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3000 connectés 

  FORUM HardWare.fr
  Programmation
  C

  fread

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

fread

n°2072374
rahela
Posté le 28-04-2011 à 16:11:32  profilanswer
 

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 :
 

Code :
  1. int test(char *fichier_bin){
  2.           FILE * f = NULL;
  3.           char c;
  4.           short int i;
  5.  
  6.           f = fopen(fichier_bin,"rb" );
  7.           printf("taille d'un char  : %d \n",sizeof(char)); // 1octet  
  8.           printf("taille d'un short int : %d \n",sizeof(short int)); // 2octets
  9.           fread(&c,sizeof(c),1,f);
  10.           printf("%d\n",c); //  affiche la valeur decimale de l'octet
  11.           fread(&i,sizeof(i),2,f); // doit normalement lire 2octets
  12.           printf("%d\n",i); // affiche la valeur decimale des deux octets
  13.           fclose(f);
  14.           return 1;
  15. }


 
 
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 :
 

Code :
  1. taille d'un char  : 1
  2. taille d'un short int : 2
  3. 8
  4. 32


 
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
 
 
 
 

mood
Publicité
Posté le 28-04-2011 à 16:11:32  profilanswer
 

n°2072375
tpierron
Posté le 28-04-2011 à 16:15:32  profilanswer
 

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.

n°2072377
olivthill
Posté le 28-04-2011 à 16:22:28  profilanswer
 

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


Message édité par olivthill le 28-04-2011 à 16:22:39
n°2072378
rahela
Posté le 28-04-2011 à 16:34:14  profilanswer
 

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
 

n°2072379
rahela
Posté le 28-04-2011 à 16:35:25  profilanswer
 

Merci olivthill, j'ai rectifié, mais les affichage c'était seulement pour vérifier les données extraites

n°2072380
shaoyin
Posté le 28-04-2011 à 16:40:42  profilanswer
 


Code :
  1. fread(&i,sizeof(i),2,f); // doit normalement lire 2octets


 
Cet appel lit en réalité 2 fois 2 octets. Tu devrais mettre 1 en troisième paramètre.

n°2072381
tpierron
Posté le 28-04-2011 à 16:41:49  profilanswer
 

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 :
  1. unsigned char buffer[2];
  2. fread(buffer, sizeof buffer, 1, f);
  3. printf("lu = %02x%02x\n", buffer[0], buffer[1]);


 
Arf, j'ai vu en plus que tu risque d'avoir un stack overflow dans ton programme :

Code :
  1. fread(&i,sizeof(i),2,f);


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.

Message cité 1 fois
Message édité par tpierron le 28-04-2011 à 16:42:47
n°2072383
shaoyin
Posté le 28-04-2011 à 16:51:28  profilanswer
 

tpierron a écrit :


D'après ce que tu affiches, ton ordinateur est en little endian (tu dois probablement être sous Windows...).


 
[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]
 

n°2072387
rahela
Posté le 28-04-2011 à 17:00:08  profilanswer
 

  1.Je remets mon code réctifié, effectivement j'ai fait des fautes de frappe dans le recopiage

Code :
  1. int test(char *fichier_bin){
  2.    2.
  3.    3.           FILE * f = NULL;
  4.    4.
  5.    5.           char c;
  6.    6.           short int i;
  7.    7. 
  8.    8.           f = fopen(fichier_bin,"rb" );
  9.    9.
  10.   10.           printf("taille d'un char  : %d \n",sizeof(char)); // 1octet   
  11.   11.           printf("taille d'un short int : %d \n",sizeof(short int)); // 2octets
  12.   12.
  13.   13.           lus = fread(&c,sizeof(char),1,f);
  14.   14.           printf("lus :%d , %d\n",lus,c); //  affiche la valeur decimale de l'octet
  15.   15.
  16.   16.           lus = fread(&i,sizeof(short int),1,f); // doit normalement lire 2octets
  17.   17.           printf("lus :%d, %d\n",lus,i); // affiche la valeur decimale des deux octets
  18.   18.
  19.   19.
  20.   20.           fclose(f);
  21.   21.
  22.   22.           return 1;
  23.   23.
  24.   24. }


 
 
et m'affiche  
 

Code :
  1. taille d'un char :1
  2. taille d'un short int :2
  3. lus :1, 8
  4. lus :1, 24608

n°2072388
tpierron
Posté le 28-04-2011 à 17:00:32  profilanswer
 

shaoyin a écrit :


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...)


 [:talen] 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.

mood
Publicité
Posté le 28-04-2011 à 17:00:32  profilanswer
 

n°2072389
rahela
Posté le 28-04-2011 à 17:01:11  profilanswer
 

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?


Message édité par rahela le 28-04-2011 à 17:02:10
n°2072391
rahela
Posté le 28-04-2011 à 17:08:26  profilanswer
 

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 ?

n°2072410
gelatine_v​elue
Posté le 28-04-2011 à 18:10:07  profilanswer
 

rahela a écrit :

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 ?

 

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.


Message édité par gelatine_velue le 28-04-2011 à 18:12:13
n°2072425
rahela
Posté le 28-04-2011 à 19:15:16  profilanswer
 

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...

n°2072440
rahela
Posté le 28-04-2011 à 20:51:42  profilanswer
 

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

n°2072441
rahela
Posté le 28-04-2011 à 20:52:04  profilanswer
 

donc je dois effectuer une inversions?

n°2072456
tpierron
Posté le 28-04-2011 à 21:43:40  profilanswer
 

rahela a écrit :

donc je dois effectuer une inversions?


Non, lis ton fichier comme une suite d'octet. De cette manière :
 

Code :
  1. unsigned char buffer[2];
  2. fread(buffer, sizeof buffer, 1, f);
  3. printf("lu = %02x%02x\n", buffer[0], buffer[1]);


 
Maintenant si tu veux manipuler (de manière portable) tes deux octets comme un nombre, tu peux écrire :

Code :
  1. i = (buffer[0]<<8) | buffer[1];


 
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.


Message édité par tpierron le 28-04-2011 à 21:46:04
n°2072481
rahela
Posté le 28-04-2011 à 23:24:11  profilanswer
 

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...


Message édité par rahela le 28-04-2011 à 23:41:03

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  fread

 

Sujets relatifs
fread stream_get_contents fonctionne pas dans ma classprobleme fread magic
fread et cache sous linuxFREAD / FWRITE
Fonction fread[module linux] fread appelle ioctl avec cmd=TCGETS ???
problème de freadfopen... fread... fwrite...
Besoin d'informations sur fread()[c windows] pb avec fread [resolut]
Plus de sujets relatifs à : fread


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR