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
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
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 en IDL qui fonctionne intégralement juste pour voir la logique :
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); }
(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
Partager