Bonjour,
J'aimerais avoir de l'aide pour réussir à lire un fichier binaire :
* L'en-tête est malgré tout en ascii et elle est donc lisible depuis un simple éditeur de texte ;
* Le reste sont des nombres codés sur 1 bit (unsigned char) sous forme d'un tableau 3D. array3D[i_PX_X,i_PX_Y,i_PX_Z].
J'ai essayé toutes les solutions décrites sur le net mais je n'arrive pas à lire correctement la partie après l'en-tête OU ALORS peut-être que je lis correctement ce tableau MAIS au final quand j'écris le tableau 3D dans un fichier texte, j'obtiens des caractères vides et des caractères en forme de rectangle.
A l'origine j'ai fais ce programme en langage IDL, pour ceux qui connaissent, et j'ai très vite trouvé la solution, mais en C++ je ne lis pas correctement les caractères entier codés sur 1 bit (en unsigned char).
Ci-dessous je mets deux solutions C++ où l'en-tête est lu correctement mais pas les caractères qui composent le tableau 3D. En dernier je poste en complément le programme d'origine (en idl) qui fonctionne pour peut-être mieux cerner ce que j'essaie de re-coder. Merci à celui qui trouvera ma bourde qui me tape fort
Soluce 1 en C++ où il y a une erreur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <new>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <stdlib.h>
using namespace std;

int main(int argc, char *argv[])
{
/////////////////////////////////////////////////////////////////////////////
////////////////////////////PARTIE QUI FONCTIONNE////////////////////////////
  string file_in;//Fichier binaire en entrée (contient une en-tete et un tableau 3D)
  string file_out="FichierSortie.txt";//Fichier texte en sortie (doit contenir uniquement le tableau 3D, sans en-tete)
  short int sizeheader_partText=512;//le header_partText comprends une partie texte de 512 caractères mais la taille totale du header est de 7424 bits.
  char * buffer;//Buffer pour lire la partie texte de l'en-tête donnant les valeurs PX_X, PX_Y et PX_Z qui définissent le nombre d'éléments du tableau 3D tableau[i_PX_X, i_PX_Y, i_PX_Z]
  string header_partText;//header_partText = buffer
  long int PX_X,PX_Y,PX_Z;

  buffer=new char[sizeheader_partText];
  if(argc != 2) exit (-1);
  file_in=argv[1];

//Ouverture du fichier binaire pour lire uniquement la partie ascii en en-tete
  ifstream fichier(file_in.c_str(), ios::in);
  if(!fichier_entree.is_open()) exit (-1);
//Lecture de l'en-tete en ascii du fichier puis fermeture
  fichier_entree.read(buffer,sizeheader_partText);
//Fermeture du fichier binaire
  fichier_entree.close();

//Reccuperation des valeurs de PX_X, PX_Y et PX_Z
  header_partText=buffer;
  delete[] buffer;
  if (!(istringstream(header_partText.substr(69,5)) >> PX_X)) PX_X = 0;//Nb pixels en X
  if (!(istringstream(header_partText.substr(74,5)) >> PX_Y)) PX_Y = 0;//Nb pixels en Y
  if (!(istringstream(header_partText.substr(79,5)) >> PX_Z)) PX_Z = 0;//Nb pixels en Z
  header_partText.clear();

  int total_size_of_header=7424;//Taille totale de l'en-tete (partie en ascii compris)
  unsigned long int size_of_array3D=PX_X*PX_Y*PX_Z;////Taille du tableau 3D tableau[i_PX_X, i_PX_Y, i_PX_Z]
////////////////////////////////////////////////////////////////////////////////////

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//\\\\\\\\\\\\\\\\\\\\\\\\\\PARTIE OU IL Y A UNE ERREUR
//Ouverture du fichier binaire pour lire le tableau 3D (contenant des nombres entiers codés sur 1bit)
  ifstream fich(file_in.c_str(),ios::binary| ios::in);
  if(!fichier_entree.is_open()) exit (-1);

  unsigned char* header=new unsigned char[total_size_of_header];
  unsigned char* array3D=new unsigned char[size_of_array3D];

//fichier_entree.seekg (0, ios::beg);
  unsigned long int i;
//Lecture de toute la partie en-tete du fichier binaire
  for (i = 0l; i < total_size_of_header; i++)
    fichier_entree.read(reinterpret_cast<char*>(&header[i]),sizeof(unsigned char));
//Lecture de tout les éléments (codés sur 1bit) du tableau 3D
  for (i = 0l; i < size_of_array3D; i++)
    fichier_entree.read(reinterpret_cast<char*>(&array3D[i]),sizeof(unsigned char));
//Fermeture du fichier binaire
  fichier_entree.close();


//Creation du fichier texte de sortie
  ofstream ficher_sortie(file_out.c_str(), ios::out | ios::trunc);  // ouverture en écriture avec effacement du fichier ouvert
  if(!ficher_sortie) exit (-1);
//Ecriture du tableau3D dans le fichier texte de sortie
  for (iPX_Z = 0; iPX_Z < PX_Z; iPX_Z++)
  {
    for (iPX_Y = 0; iPX_Y < PX_Y; iPX_Y++)
    {
      cpt=0;
      for (iPX_X = 0; iPX_X < PX_X; iPX_X++)
      {
        ficher_sortie << array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X] << "  ";
        if(cpt == 18)
        {
          ficher_sortie << endl;
          cpt=0;
        }
        else cpt++;
      }
      ficher_sortie << endl;
    }
  }
//Fermeture du fichier texte de sortie
  ficher_sortie.close();
//Liberation espace memoire
  delete[] header;
  delete[] array3D;
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  return (0);
}
Soluce 2 en C++ où j'ai aussi une erreur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <new>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <stdlib.h>
using namespace std;

int main(int argc, char *argv[])
{
/////////////////////////////////////////////////////////////////////////////
////////////////////////////PARTIE QUI FONCTIONNE////////////////////////////
  string file_in;//Fichier binaire en entrée (contient une en-tete et un tableau 3D)
  string file_out="FichierSortie.txt";//Fichier texte en sortie (doit contenir uniquement le tableau 3D, sans en-tete)
  short int sizeheader_partText=512;//le header_partText comprends une partie texte de 512 caractères mais la taille totale du header est de 7424 bits.
  char * buffer;//Buffer pour lire la partie texte de l'en-tête donnant les valeurs PX_X, PX_Y et PX_Z qui définissent le nombre d'éléments du tableau 3D tableau[i_PX_X, i_PX_Y, i_PX_Z]
  string header_partText;//header_partText = buffer
  long int PX_X,PX_Y,PX_Z;

  buffer=new char[sizeheader_partText];
  if(argc != 2) exit (-1);
  file_in=argv[1];

//Ouverture du fichier binaire pour lire uniquement la partie ascii en en-tete
  ifstream fichier(file_in.c_str(), ios::in);
  if(!fichier_entree.is_open()) exit (-1);
//Lecture de l'en-tete en ascii du fichier puis fermeture
  fichier_entree.read(buffer,sizeheader_partText);
//Fermeture du fichier binaire
  fichier_entree.close();

//Reccuperation des valeurs de PX_X, PX_Y et PX_Z
  header_partText=buffer;
  delete[] buffer;
  if (!(istringstream(header_partText.substr(69,5)) >> PX_X)) PX_X = 0;//Nb pixels en X
  if (!(istringstream(header_partText.substr(74,5)) >> PX_Y)) PX_Y = 0;//Nb pixels en Y
  if (!(istringstream(header_partText.substr(79,5)) >> PX_Z)) PX_Z = 0;//Nb pixels en Z
  header_partText.clear();

  int total_size_of_header=7424;//Taille totale de l'en-tete (partie en ascii compris)
  unsigned long int size_of_array3D=PX_X*PX_Y*PX_Z;////Taille du tableau 3D tableau[i_PX_X, i_PX_Y, i_PX_Z]
///////////////////////////////////////////////////////////////////////////////////

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//||||||||||||||||||||||||||PARTIE OU IL Y A UNE ERREUR||||||||||||||||||||||||||||
//Ouverture du fichier binaire pour lire le tableau 3D (contenant des nombres entiers codés sur 1bit)
  ifstream fich(file_in.c_str(),ios::binary| ios::in);
  if(!fichier_entree.is_open()) exit (-1);

  unsigned char* header=new unsigned char[total_size_of_header];
  unsigned char* array3D=new unsigned char[size_of_array3D];

//fichier_entree.seekg (0, ios::beg);
//Lecture de toute la partie en-tete du fichier binaire
  fich.read(reinterpret_cast<char*>(header),total_size_of_header*sizeof(unsigned char));
//Lecture de tout les éléments (codés sur 1bit) du tableau 3D
  fich.read(reinterpret_cast<char*>(array3D),size_of_array3D*sizeof(unsigned char));
//Fermeture du fichier binaire
  fichier_entree.close();


//Creation du fichier texte de sortie
  ofstream ficher_sortie(file_out.c_str(), ios::out | ios::trunc);  // ouverture en écriture avec effacement du fichier ouvert
  if(!ficher_sortie) exit (-1);
//Ecriture du tableau3D dans le fichier texte de sortie
  for (iPX_Z = 0; iPX_Z < PX_Z; iPX_Z++)
  {
    for (iPX_Y = 0; iPX_Y < PX_Y; iPX_Y++)
    {
      cpt=0;
      for (iPX_X = 0; iPX_X < PX_X; iPX_X++)
      {
        ficher_sortie << array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X] << "  ";
        if(cpt == 18)
        {
          ficher_sortie << endl;
          cpt=0;
        }
        else cpt++;
      }
      ficher_sortie << endl;
    }
  }
//Fermeture du fichier texte de sortie
  ficher_sortie.close();
//Liberation espace memoire
  delete[] header;
  delete[] array3D;
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  return (0);
}
Soluce en IDL qui fonctionne intégralement juste pour voir la logique :
(pas besoin de connaitre ce langage pour comprendre ce que les lignes de code veulent dire)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pro program, file_in
 
file_out='FichierSortie.txt'
;*******************************************************************************
;Ouverture du fichier binaire en entree
TMP=''
openr, unit, file_in, ERROR = err, /get_lun
if (err ne 0) then exit
;Lecture de la partie texte de l'en-tete du fichier FIS puis fermeture
readf,unit,TMP,FORMAT='(A512)'
;Fermeture du fichier binaire
free_lun, unit
PX_X = long(STRMID(TMP,69,5));Nb pixels en X
PX_Y = long(STRMID(TMP,74,5));Nb pixels en Y
PX_Z = long(STRMID(TMP,79,5));Nb pixels en Z
TMP=''
;*******************************************************************************
;*******************************************************************************
;Ouverture du fichier binaire en entree
openr, unit, file_in, ERROR = err, /get_lun
if (err ne 0) then exit
 
;Allocation memoire du header et du tableau 3D contenu dans le fichier binaire (nombres entiers codés sur 1bit)
header=bytarr(PX_X,2); PX_X*2=7424 bits
array3D=bytarr(PX_X,PX_Y,PX_Z)
 
;Lecture de toute la partie en-tete du fichier binaire
readu,unit,header
;Lecture de tout les éléments (codés sur 1bit) du tableau 3D
readu,unit,array3D
 
;Fermeture du fichier binaire
free_lun, unit
;*******************************************************************************
;*******************************************************************************
;Ouverture du fichier texte en sortie
openw,unit,file_out,ERROR=err, /get_lun
if (err ne 0) then exit
 
;Ecriture du tableau 3D dans le fichier texte puis fermeture
printf, unit, array3D
;Fermeture du fichier texte
free_lun, unit
;*******************************************************************************
end