chtite question sur les flux de fichiers

chtite question sur les flux de fichiers - C++ - Programmation

Marsh Posté le 17-07-2002 à 10:58:11    

Bon, vu la rapidité avec laquelle mon problème sur les dlls a été réglé, je tente une deuxième question :D
Je voudrais lire des en-têtes de fichiers, à l'aide de flux (ifstream machin (lefichier),  machin.read (lehader))
Et bien sur en binaire hein.
Bon mais je sais que y a pleins de trucs compliqué à l'échelle des bits, du genre les words dans les dwords sont inversé (0xAB CD devient 0xCD AB ou un truc comme ça), et pis est-ce que read lis bien dans l'ordre (j'espere qd même ;)), et enfin est-ce qu'il y a un moyen que si je crée :

Code :
  1. struct sHeader
  2.    {
  3.    int machin;
  4.    char bidule;
  5.    long truc;
  6.    }Header;


Machin soit bien le 1er en mem, suivit de bidule et de truc, histoire de pouvoir faire un read (&Header), si jamais read remet bien les bits dans l'ordre bien sur ...
 
Oula je crois que j'ai rarement posté un truc aussi peu clair ... :D Mais bon les gens d'ici sont tellemet bon ... nan, si vous avez des précisions à demander j'expliquerai ;)

Reply

Marsh Posté le 17-07-2002 à 10:58:11   

Reply

Marsh Posté le 17-07-2002 à 11:01:21    

Bonne question, ça m'intéresse aussi :D

Reply

Marsh Posté le 17-07-2002 à 11:03:06    

freewol a écrit a écrit :

Bon mais je sais que y a pleins de trucs compliqué à l'échelle des bits, du genre les words dans les dwords sont inversé


big endian / little endian. ça dépend de ton proc : intel, mac, etc.
 

freewol a écrit a écrit :

Machin soit bien le 1er en mem, suivit de bidule et de truc, histoire de pouvoir faire un read (&Header), si jamais read remet bien les bits dans l'ordre bien sur ...


en théorie, oui. en théorie, car le compilateur peut décider d'aligner tes variables (sur word, sur dword). relis le fichier avec d'autres options de compilation, tu l'as dans l'os.

Reply

Marsh Posté le 17-07-2002 à 11:04:24    

ben moi j'ai souvent fait ce genre de manip, et je n'ai eu aucun problème, les zones de mémoire étaient bien contigues
 
je suppose que quand on déclare une structure, le compilo se débrouille pour allouer une zone de RAM suffisamment large...


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 11:06:06    

Vaut mieux éviter de faire un read/write bestiale de structure, par contre pour les types atomique de plus d'un octets (int, double...) Tant que tu écrit et que tu lis sur des machines qui ont le même type de processeur c bon.


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:06:45    

euh ... bon pour le truc qui dépend du proc, j'ose espérer que c'est qd même pareil pour tout ce qui se trouve sur PC (intel, amd, cyrix (:D)), non ? Sinon je suis pas dans la merde ... :sweat:
 
Ensuite pour l'alignement en mem, est-ce que ça veut dire que le seul moyen de ne pas avoir de problème c'est de lire les infos par petits bouts du genre read(&Header.machin), puis read(&Header.bidule) puis read(&Header.truc) ... ? Si c le cas ça tue un peu (bcp) l'intérêt d'avoir une struct ... :(
 
 

Reply

Marsh Posté le 17-07-2002 à 11:07:43    

Harkonnen a écrit a écrit :

ben moi j'ai souvent fait ce genre de manip, et je n'ai eu aucun problème, les zones de mémoire étaient bien contigues
 
je suppose que quand on déclare une structure, le compilo se débrouille pour allouer une zone de RAM suffisamment large...




 
Ha mon avis tu peux avoir des problèmes si tu utilise pas le même compilo pour faire le prog qui lit et celui qui écrit (je sais ça peut paraitre stupide mais on sait jamais :) ) d'autant plus si tu utilise des int.


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:08:29    

freewol a écrit a écrit :

euh ... bon pour le truc qui dépend du proc, j'ose espérer que c'est qd même pareil pour tout ce qui se trouve sur PC (intel, amd, cyrix (:D)), non ? Sinon je suis pas dans la merde ... :sweat:
 




 
Tant que tu reste sur une plateforme Pc ça doit être bon.
 


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:10:02    

freewol a écrit a écrit :

 
Ensuite pour l'alignement en mem, est-ce que ça veut dire que le seul moyen de ne pas avoir de problème c'est de lire les infos par petits bouts du genre read(&Header.machin), puis read(&Header.bidule) puis read(&Header.truc) ... ? Si c le cas ça tue un peu (bcp) l'intérêt d'avoir une struct ... :(
 
 
 




 
Normalement ça doit passer, sauf si tu cherche les enuis avec des truc exotiques :D


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:10:18    

freewol a écrit a écrit :

euh ... bon pour le truc qui dépend du proc, j'ose espérer que c'est qd même pareil pour tout ce qui se trouve sur PC (intel, amd, cyrix (:D)), non ? Sinon je suis pas dans la merde ... :sweat:




à partir du moment ou tu ne codes pas pour des procs motorola... tous les processeurs intel ou compatibles codent leurs octets en little endian.
 

freewol a écrit a écrit :

 
Ensuite pour l'alignement en mem, est-ce que ça veut dire que le seul moyen de ne pas avoir de problème c'est de lire les infos par petits bouts du genre read(&Header.machin), puis read(&Header.bidule) puis read(&Header.truc) ... ? Si c le cas ça tue un peu (bcp) l'intérêt d'avoir une struct ... :(



franchement, vu le nombre de fois ou j'ai lu ou écrit une structure en bloc sans aucun pb, je me demande vraiment si c'est source d'emmerdement
 
 
 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 11:10:18   

Reply

Marsh Posté le 17-07-2002 à 11:12:11    

Harkonnen a écrit a écrit :

franchement, vu le nombre de fois ou j'ai lu ou écrit une structure en bloc sans aucun pb, je me demande vraiment si c'est source d'emmerdement




 
Pour avoir des problèmes faut vraiment les chercher à mon avis


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:14:39    

Harkonnen a écrit a écrit :

franchement, vu le nombre de fois ou j'ai lu ou écrit une structure en bloc sans aucun pb, je me demande vraiment si c'est source d'emmerdement


ce n'est pas une source d'emmerdements, c'est un design qui dit : c'est CETTE structure qu'on utilise, on ne la changera JAMAIS (en gros). si tu veux faire évoluer ta structure, tu as intérêt à sauvegarder chaque variable avec son nom, un peu comme les attributs d'une balise html. _là_ tu n'auras jamais d'emmerdes, tu ne te prendras moins la tête avec des numéros de version, etc.

Reply

Marsh Posté le 17-07-2002 à 11:15:13    

un exemple de soft que j'ai fait et qui écrit une structure en bloc :
 
http://harko.free.fr/soft/ID3_2_CSV.exe
 
c'est un prog qui exporte les tags ID3 de fichiers mp3 en CSV. je déclare une structure correspondant au tag et je fais un read sauvage dans &structure. aucun pb.
 
vérifieé, vous verrez ! :)


Message édité par Harkonnen le 17-07-2002 à 11:24:22

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 11:16:27    

youdontcare a écrit a écrit :

ce n'est pas une source d'emmerdements, c'est un design qui dit : c'est CETTE structure qu'on utilise, on ne la changera JAMAIS (en gros). si tu veux faire évoluer ta structure, tu as intérêt à sauvegarder chaque variable avec son nom, un peu comme les attributs d'une balise html. _là_ tu n'auras jamais d'emmerdes, tu ne te prendras moins la tête avec des numéros de version, etc.




ah mais la je suis d'accord !  
si la structure n'évolue pas, cette manip est sans danger, la c'est clair !


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 11:17:46    

Harkonnen a écrit a écrit :

un exemple de soft que j'ai fait et qui écrit une structure en bloc :
 
http://harko.free.fr/soft/id3_2_csv.exe
 
c'est un prog qui exporte les tags ID3 de fichiers mp3 en CSV. je déclare une structure correspondant au tag et je fais un read sauvage dans &structure. aucun pb.
 
vérifieé, vous verrez ! :)




 
On a jamais dit que ça marchait pas, je l'ai souvent fais moi aussi :)


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:19:11    

bon ok donc si je résume, étant donné que je ne code que pour PC (euh ... windows c bien que pour PC non ? :D), je me pose pas de question sur les bits écris sur le DD. Ensuite si je joue pas de malchance j'aurai pas de problème avec un read sauvage de structure.
 
Bon tout ça c très bien, mais (et oui il y a un mais) :
est-ce qu'il faut que je tienne compte de ce petit ou grand indien, je ne sais même pas si ça correspond à ce que je disais (inversion des dwords) ????? :??:
Et pkoi, oui pkoi, qd je tente ce que j'ai dis avec un fichier bmp, non seulement ça foire, puisque j'ai que qques champs qui sont bons, mais en plus suivant si je read la structure d'un coup d'un seul ou par ptits bouts j'ai certains champs qui sont bons ou non ? Bon mais là pour cette dernière question il est encore possible que ça vienne de mon code, que je n'ai pas totalement vérifié, svp répondez surtout à celles plus théoriques.
 
En tout cas merci pour vos réponses

Reply

Marsh Posté le 17-07-2002 à 11:26:13    

C littleEndian (un truc comme ça), ça veut dire que les octets de poid faibles sont en premier, pour écrire 0xFF00 le proc met 00 FF (dans la mémoir ou sur le disque) Et tant que tu code pour le même type de proc c bon.


Message édité par LetoII le 17-07-2002 à 11:27:32

---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:27:39    

sur les procs intel, la suite d'octets suivante :

Citation :


04 08 03 05


 
sera codée comme ça en mémoire :

Citation :


05 03 08 04


 
mais en mémoire uniquement ! après, le compilateur se débrouille à remettre ça dans l'ordre (à confirmer néanmoins).
 
donc à mon avis, je pense que tu n'as meme pas à te casser le c.. à remettre tout ça en ordre
 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 11:33:28    

Harkonnen a écrit a écrit :

donc à mon avis, je pense que tu n'as meme pas à te casser le c.. à remettre tout ça en ordre
 
 




 
Effectivement le compilo fait ce qu'il faut et tu n'as pas à t'en occuper lorsque tu écrit ton code. Attention cependant avec les images, tu peux avoir des surprises en ce qui concerne l'écriture des couleurs (j'ai eu le problème).


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 11:49:37    

ok bon j'essaie tout ça, et je vous tiens au courant.
merci à tous :jap:

Reply

Marsh Posté le 17-07-2002 à 12:13:26    

:sweat:
Bon ben les ennuis commence, je suis dsl mais je risque de poser encore une question stupide ...
C parti :  
J'essaie de lire le header d'un bête BMP, et ça foire déjà. Bon ce BMP ouvert avec Hex Workshop se révèle commencer par 42 4D C4 0D 02 00. 42 et 4D ça c l'identifiant, 2 chars : 'BM', et C4 0D 02 00, qui sont donc inversés et signifient donc 00 02 0D C4, soit 134596 comme le confirment la calculatrice et Hex Worshop lui même, c'est la taille. Bon ensuite le prog qui tente de lire ça (oui juste ça :() :

Code :
  1. struct sHeader
  2. {
  3. char Identifier [2];
  4. DWORD FileSize;
  5. }Header;
  6. ...
  7. BMP.read ((BYTE *)&Header, sizeof(Header));
  8. ofstream txt ("c:\\infos.txt" );
  9. txt << "Identifier : '" << Header.Identifier[0] << Header.Identifier[1] << "'\n";
  10. txt << "FileSize : " << Header.FileSize << "\n";


Bon ben ça ça marche pas puisque j'obtient :
Identifier : 'BM'
FileSize : 2
:sweat:
Par contre (!!), si je fais le read comme ça :

Code :
  1. BMP.read ((BYTE *)&Header.Identifier, sizeof(Header.Identifier));
  2. BMP.read ((BYTE *)&Header.FileSize, sizeof (Header.FileSize));


et bien j'obtiens bien :
Identifier : 'BM'
FileSize : 134596
 
... :sweat:

Reply

Marsh Posté le 17-07-2002 à 12:17:35    

Citation :


BMP.read ((BYTE *)&Header, sizeof(Header));


 
Pourquoi tu castes ???


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 12:19:12    

ben parce que le prototype de read c read (unsigned char *, ...)

Reply

Marsh Posté le 17-07-2002 à 12:22:35    

Essaie plutot :

Code :
  1. sizeof (struct sHeader);


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 12:31:43    

Harkonnen a écrit a écrit :

Essaie plutot :

Code :
  1. sizeof (struct sHeader);






 
Hum, non, pareil (encore heureux).

Reply

Marsh Posté le 17-07-2002 à 14:09:45    

C quoi ta variable BMP comme type?


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 14:11:30    

au fait, t'utilises quoi comme compilo ?
si c'est GCC, c'est normal


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 14:13:54    

Bon contre toute attente j'ai compris d'où venait le problème ... et ça montre que tout n'est pas tjs aussi simple que les posts précédant pouvaient laisser penser. Je pense que c un problème du à read de ifstream, mais la cause elle-même du problème de read est l'inversion des octets due aux indiens.
 
Le truc, c'est que ça marche très bien qd les dwords à lire sont alignés en mem, mais ça ne marche plus du tout quand des words ou des bytes seuls viennent tout déranger.
 
Un exemple : si on a  

Code :
  1. struct sExemple
  2. {
  3. WORD word1;
  4. DWORD dword1;
  5. DWORD dword2;
  6. WORD word2;
  7. DWORD dword3;
  8. }Exemple;


et qu'ensuite on fait un read (&Exemple), et bien le word1 sera bon, mais les dwords1 et dword2 ne le seront pas, tandis que dword3 le sera à nouveau !! (word2 j'en sais rien)
Et si on fait ça :

Code :
  1. struct sExemple
  2. {
  3. WORD word1;
  4. WORD word2;
  5. DWORD dword1;
  6. DWORD dword2;
  7. }Exemple;


ou ça :

Code :
  1. struct sExemple
  2. {
  3. BYTE byte1;
  4. BYTE byte2;
  5. BYTE byte3;
  6. BYTE byte4;
  7. DWORD dword1;
  8. }Exemple;


et bien ça marche ...
Bon j'ai un peu écrit un roman, dsl.
J'espere avoir été clair, parce que j'y connais rien à ça, je décris juste le résulat d'expériences extrapolé ...


Message édité par freewol le 17-07-2002 à 14:16:08
Reply

Marsh Posté le 17-07-2002 à 14:16:41    

Tu l'as bien ouvert en binaire ton ifstream?


Message édité par LetoII le 17-07-2002 à 14:16:53

---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 14:18:00    

as tu ouvert ton ifstream en binary ?
 
edit : grilled :d


Message édité par Harkonnen le 17-07-2002 à 14:19:11

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 14:19:01    

Harkonnen a écrit a écrit :

as tu ouvert ton ifstream en binary ?




 
Grillé :D


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 14:21:19    

ouiouiouiouiouiouiouiouiouiouiouiouiouiouioui

Citation :


Et bien sur en binaire hein.  


Eh oui faut de la mémoire ;) Dsl :sweat:

Reply

Marsh Posté le 17-07-2002 à 14:22:04    

t'utilises GCC ou pas ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 14:23:03    

On sait jamais.
2eme explication: ton compilo fait un allignement de la mémoir à la con et te rajoute 2 octets à la suite de ton tableau.
Vérifie la taille de ta structure.


Message édité par LetoII le 17-07-2002 à 14:35:18

---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 14:27:13    

consulte ça éventuellement :
 
http://www.phim.unibe.ch/comp_doc/ [...] izeof.html
http://www.delorie.com/djgpp/v2faq/faq22_11.html


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-07-2002 à 14:30:07    

bon déjà non j'[/cpp]utilise VC++6 sous win98
 
ensuite je sais ce qu'il se passe exactement pour ma structure de BMP :  

Code :
  1. struct BMPHeader
  2. {
  3. char  Identifier [2];
  4. DWORD FileSize;
  5. DWORD Reserved;
  6. DWORD DataOffset;
  7. DWORD HeaderSize;
  8. ...
  9.         };


Ensuite mon fichier commence par : 42 4D C4 0D 02 00 00 00 00 00 36 00 00 00 28 00(oui ça fait bcp de chiffres :D)
Eh bien si je lis tout d'un coup, 42 et 4D sont bien convertis en char : 'B' et 'M'. Ensuite C4 0D sont oubliés ! Puis on inverse : 02 00 00 00 devient 00 00 00 02 d'où la taille de 2, puis 00 00 36 00 devient 00 36 00 00 et 00 00 28 00 devient 00 28 00 00. Hum bon j'en ai fait un peu trop, tant pis je laisse. Enfin bref, si le lis en 1er les 2 chars, 42 et 4D ne sont plus oubliés. Le truc c'est read aligne tout suivant les multiples de 4 à partir du début où on lis apparemment. Par contre ensuite dans l'en-tête il y a 2 words de suite et ça passe très bien (ils sont pas inversés entre eux).


Message édité par freewol le 17-07-2002 à 14:35:01
Reply

Marsh Posté le 17-07-2002 à 14:37:20    

freewol a écrit a écrit :

bon déjà non j'[/cpp]utilise VC++6 sous win98
 
ensuite je sais ce qu'il se passe exactement pour ma structure de BMP :  

Code :
  1. struct BMPHeader
  2. {
  3. char  Identifier [2];
  4. DWORD FileSize;
  5. DWORD Reserved;
  6. DWORD DataOffset;
  7. DWORD HeaderSize;
  8. ...
  9.         };


Ensuite mon fichier commence par : 42 4D C4 0D 02 00 00 00 00 00 36 00 00 00 28 00(oui ça fait bcp de chiffres :D)
Eh bien si je lis tout d'un coup, 42 et 4D sont bien convertis en char : 'B' et 'M'. Ensuite C4 0D sont oubliés ! Puis on inverse : 02 00 00 00 devient 00 00 00 02 d'où la taille de 2, puis 00 00 36 00 devient 00 36 00 00 et 00 00 28 00 devient 00 28 00 00. Hum bon j'en ai fait un peu trop, tant pis je laisse. Enfin bref, si le lis en 1er les 2 chars, 42 et 4D ne sont plus oubliés. Le truc c'est read aligne tout suivant les multiples de 4 à partir du début où on lis apparemment. Par contre ensuite dans l'en-tête il y a 2 words de suite et ça passe très bien (ils sont pas inversés entre eux).




 
Par ce que les donnée doivent être allignée sur 32 bits par ton compilo. T'as essayé de reagrdé ce que te renvoi sizeof sur ta structure?


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 15:43:28    

ah ok ... ok ça y est je viens de comprendre le rapport avec les trucs sur sizeof de tout à l'heure. Au temps pour moi. Je regarderai ça. Mais ça expliquerai bien les choses. Ce qui est bien c'est que je comprends vite. Ce qui l'est moins, c qu'il faut m'expliquer longtps :sweat:
Merci :jap:

Reply

Marsh Posté le 17-07-2002 à 15:45:15    

freewol a écrit a écrit :

ah ok ... ok ça y est je viens de comprendre le rapport avec les trucs sur sizeof de tout à l'heure. Au temps pour moi. Je regarderai ça. Mais ça expliquerai bien les choses. Ce qui est bien c'est que je comprends vite. Ce qui l'est moins, c qu'il faut m'expliquer longtps :sweat:
Merci :jap:




 
 :lol:


---------------
Le Tyran
Reply

Marsh Posté le 17-07-2002 à 15:48:26    

freewol a écrit a écrit :

est-ce qu'il faut que je tienne compte de ce petit ou grand indien



 

freewol a écrit a écrit :

la cause elle-même du problème de read est l'inversion des octets due aux indiens



je voudrais savoir si tu le fais exprès :D

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed