IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Pb de Lecture d'un fichier binaire (mais avec en-tête en texte ascii)


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut Pb de Lecture d'un fichier binaire (mais avec en-tête en texte ascii)
    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

  2. #2
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Bonjour.

    Je pense que c'est un simple problème de cast: tu t'attend à voir apparaitre des nombres dans ton fichier de sortie, mais puisque array3D est du type char (qui est apparement considéré comme identique au unsigned char par ton compilateur)mais tu ne lis que des chars donc forcément, il l'interprète comme des caractères ascii et non comme des nombres.

    Je te propose donc de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficher_sortie << array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X] << "  ";
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficher_sortie << static_cast<unsigned int>(array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X]) << "  ";
    ça devrait faire la conversion

    ensuite, il y a peut-être plus élégant (par exemple avec des flags d'interpétation), mais je me rapelle plus comment on les utilise.

    PS: Je n'ai regardé que le premier code, je suis trop flemmard pour lire le second.

    Bonne Chance
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par méphistopheles Voir le message
    Bonjour.

    Je pense que c'est un simple problème de cast: tu t'attend à voir apparaitre des nombres dans ton fichier de sortie, mais puisque array3D est du type char (qui est apparement considéré comme identique au unsigned char par ton compilateur)mais tu ne lis que des chars donc forcément, il l'interprète comme des caractères ascii et non comme des nombres.

    Je te propose donc de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficher_sortie << array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X] << "  ";
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ficher_sortie << static_cast<unsigned int>(array3D[PX_Y*PX_X*iPX_Z+PX_X*iPX_Y+iPX_X]) << "  ";
    ça devrait faire la conversion

    ensuite, il y a peut-être plus élégant (par exemple avec des flags d'interpétation), mais je me rapelle plus comment on les utilise.

    PS: Je n'ai regardé que le premier code, je suis trop flemmard pour lire le second.

    Bonne Chance

    MON SAUVEUR !!!!!!!!!!!!!!!!!!!
    MILLE MERCIS !
    Tu m'as sortie de mon cauchemar éveillé !
    Ouf, sacré soulagement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/12/2006, 13h06
  2. lecture d'un fichier binaire
    Par booby dans le forum C
    Réponses: 17
    Dernier message: 20/09/2006, 16h11
  3. lecture d'un fichier binaire
    Par Tonta dans le forum C++
    Réponses: 1
    Dernier message: 14/04/2006, 06h53
  4. lecture d'un fichier binaire en VB
    Par olivier] dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 28/12/2005, 11h17
  5. Lecture d'un fichier binaire
    Par Gloubie dans le forum Langage
    Réponses: 9
    Dernier message: 05/12/2005, 12h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo