[RESOLU] pb avec un fichier binaire et vc

pb avec un fichier binaire et vc [RESOLU] - C++ - Programmation

Marsh Posté le 18-08-2007 à 14:25:24    

Le problème vient du type size_t :
 

Citation :

In Visual C++ 2005, time is a wrapper for _time64 and time_t is, by default, equivalent to __time64_t. If you need to force the compiler to interpret time_t as the old 32-bit time_t, you can define _USE_32BIT_TIME_T. This is not recommended because your application may fail after January 18, 2038; the use of this macro is not allowed on 64-bit platforms.


 


Message édité par moumout511 le 24-08-2007 à 13:15:28
Reply

Marsh Posté le 18-08-2007 à 14:25:24   

Reply

Marsh Posté le 18-08-2007 à 15:01:46    

pq ne pas faire une structure et tout lire d'un seul coup ?

Reply

Marsh Posté le 18-08-2007 à 19:51:17    

le fichier a été généré sous quoi ?
il te reste plus qu'a traçer au debug pour voir où le décalage se produit.

Reply

Marsh Posté le 18-08-2007 à 20:05:53    

Tu as vérifié l'endianess du processeur?
 
Si tu ne lis pas des données qui ont été générées avec le meme type de processeur -- little ou big endian -- le contenu des variables est chamboulé car elles ne seront pas stockées dans le meme ordre. Ex: (vieux) Mac et PC.
 
S'il s'agit de lire peu de données de config par exemple alors c'est alors bien plus robuste de passer par un fichier en texte (à la XML).
Sinon tu peux lire et ecrire octet par octet, et enfin si le fichier vient d'une source différente ou qu'il est normalisé et que tu peux pas changer son format, tu devras tester l'endianess et retourner les octets à la main si besoin. Sans indication et sans connaitre le type de cpu qui a écrit les données il faudra le "deviner", comme ici en pensant que -154 est un bon indicateur que l'endianess à changé entre l'écriture et ta lecture.

Reply

Marsh Posté le 18-08-2007 à 22:55:40    

bjone a écrit :

le fichier a été généré sous quoi ?
il te reste plus qu'a traçer au debug pour voir où le décalage se produit.


 
Normalement, le fichier a été généré avec le même programme qui sert à le lire mais le programme est multiplateforme, je ne sais donc pas sur quel os/système.
 

jimko a écrit :

Tu as vérifié l'endianess du processeur?
 
Si tu ne lis pas des données qui ont été générées avec le meme type de processeur -- little ou big endian -- le contenu des variables est chamboulé car elles ne seront pas stockées dans le meme ordre. Ex: (vieux) Mac et PC.
 
S'il s'agit de lire peu de données de config par exemple alors c'est alors bien plus robuste de passer par un fichier en texte (à la XML).
Sinon tu peux lire et ecrire octet par octet, et enfin si le fichier vient d'une source différente ou qu'il est normalisé et que tu peux pas changer son format, tu devras tester l'endianess et retourner les octets à la main si besoin. Sans indication et sans connaitre le type de cpu qui a écrit les données il faudra le "deviner", comme ici en pensant que -154 est un bon indicateur que l'endianess à changé entre l'écriture et ta lecture.


 
J’avais bien pensé au problème de l’endian mais cela n’explique pas pourquoi  l’exécutable téléchargé  pour Windows arrive à lire ce binaire sans problème. Le fichier contient des données de configuration et des points de mesures (plusieurs dizaines de milliers).

Reply

Marsh Posté le 18-08-2007 à 23:12:19    

Une erreur courante est de faire l'ouverture du fichier sans spécifier le mode binaire, et dans ce cas, pas de chance car c'est le mode texte qui est le mode par défaut.

Reply

Marsh Posté le 19-08-2007 à 13:07:13    

billgatesanonym a écrit :

Une erreur courante est de faire l'ouverture du fichier sans spécifier le mode binaire, et dans ce cas, pas de chance car c'est le mode texte qui est le mode par défaut.


 
Le fichier est bien ouvert en mode binaire :
 

Code :
  1. FILE *fp = fopen(mFileName, "rb" );

Reply

Marsh Posté le 19-08-2007 à 15:41:30    

Le programme ci-dessous permet de tester le problème de l’endian et de l’hypothétique problème d’incompatibilité de fonctions du C incorporés dans un projet  C++ :
 

Code :
  1. #include "stdafx.h"
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <algorithm>
  6. using namespace std;
  7. #define ByteSwap5(x) ByteSwap((unsigned char *) &x,sizeof(x))
  8. void ByteSwap(unsigned char * b, int n)
  9. {
  10.    register int i = 0;
  11.    register int j = n-1;
  12.    while (i<j)
  13.    {
  14.       swap(b[i], b[j]);
  15.       i++, j--;
  16.    }
  17. }
  18. int main(int argc, char* argv[])
  19. {
  20. FILE *fp;
  21. fp = fopen("C:\\Documents and Settings\\Ludo\\Bureau\\ezdata\\sample\\sample1.ezd","rb" );
  22. if (!fp)
  23. {
  24.  printf("Probleme d'ouverture de fichier\n" );
  25. }
  26. else
  27. {
  28.  char Name1[100];
  29.  time_t Time1;
  30.  float StepX1, StepY1, XStart1;
  31.  long Number1;
  32.  fread(Name1,     sizeof(char),   100, fp);
  33.  fread(&Time1,    sizeof(time_t), 1, fp);
  34.  fread(&StepX1,   sizeof(float),  1, fp);
  35.  fread(&StepY1,   sizeof(float),  1, fp);
  36.  fread(&XStart1,  sizeof(float),  1, fp);
  37.  fread(&Number1,  sizeof(long),   1, fp);
  38.  fclose(fp);
  39.  cout<<"Test avec fread:"<<endl;
  40.  cout<<"Name="<<Name1<<endl;
  41.  cout<<"Time="<<Time1<<endl;
  42.  cout<<"StepX="<<StepX1<<endl;
  43.  cout<<"StepY="<<StepY1<<endl;
  44.  cout<<"XStart="<<XStart1<<endl;
  45.  cout<<"Number="<<Number1<<endl;
  46. }
  47. ifstream f("C:\\Documents and Settings\\Ludo\\Bureau\\ezdata\\sample\\sample1.ezd",ios::in|ios::binary);
  48. if(!f.is_open())cout<<"Impossible d'ouvrir le fichier en lecture !"<<endl;
  49. else
  50. {
  51.  char Name2[100];
  52.  time_t Time2;
  53.  float StepX2, StepY2, XStart2;
  54.  long Number2;
  55.  for(size_t i=0;i<100;i++){f.read((char *)&Name2[i],sizeof(char));}
  56.  f.read((char *)&Time2,sizeof(time_t));
  57.  f.read((char *)&StepX2,sizeof(float));
  58.  f.read((char *)&StepY2,sizeof(float));
  59.  f.read((char *)&XStart2,sizeof(float));
  60.  f.read((char *)&Number2,sizeof(long));
  61.  f.close();
  62.  cout<<"Test avec ifstream::read:"<<endl;
  63.  cout<<"Name="<<Name2<<endl;
  64.  cout<<"Time="<<Time2<<endl;
  65.  cout<<"StepX="<<StepX2<<endl;
  66.  cout<<"StepY="<<StepY2<<endl;
  67.  cout<<"XStart="<<XStart2<<endl;
  68.  cout<<"Number="<<Number2<<endl;
  69.  ByteSwap5(Time2);
  70.  ByteSwap5(StepX2);
  71.  ByteSwap5(StepY2);
  72.  ByteSwap5(XStart2);
  73.  ByteSwap5(Number2);
  74.  cout<<"Swap:"<<endl;
  75.  cout<<"Time="<<Time2<<endl;
  76.  cout<<"StepX="<<StepX2<<endl;
  77.  cout<<"StepY="<<StepY2<<endl;
  78.  cout<<"XStart="<<XStart2<<endl;
  79.  cout<<"Number="<<Number2<<endl;
  80. }
  81.  
  82. return 0;
  83. }


 
Résultats:
 
Test avec fread:
Name=__ezGet.net dataFormat 5__This is the <u>native data</u> for ezDatar.
<font size='+4'>Now</font>, yo╠╠╠╠╠╠╠╠`↔1►╠╠╠╠üÏ■9¿ ↕
Time=8319591545089237109
StepX=8.67581e+020
StepY=4.51558e+027
XStart=0.0140029
Number=540959279
Test avec ifstream::read:
Name=__ezGet.net dataFormat 5__This is the <u>native data</u> for ezDatar.
<font size='+4'>Now</font>, yo╠╠╠╠╠╠╠╠PrQ►♦
Time=8319591545089237109
StepX=8.67581e+020
StepY=4.51558e+027
XStart=0.0140029
Number=540959279
Swap:
Time=8439854971802908019
StepX=4.72933e+022
StepY=0.237707
XStart=2.92643e+029
Number=794967584
Appuyez sur une touche pour continuer...
 
Ce test montre que pour les fonctions du C et les méthodes du C++ renvoient les mêmes valeurs, sauf pour la chaîne de caractères (???). Le swap des bits ne change rien, les valeurs sont toujours aussi catastrophiques...

Reply

Marsh Posté le 19-08-2007 à 21:24:44    

pb de 0 en fin de chaine.

Reply

Sujets relatifs:

Leave a Replay

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