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 :

Problème de cast à la lecture de short int dans un fichier bin


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 Problème de cast à la lecture de short int dans un fichier bin
    Bonjour,

    J'ai fais un code très simple pour manipuler l'écriture d'un vecteur 2D(6,4) dans un fichier binaire que je relis pour vérifier que le résultat est bien correct.
    Mais j'obtiens des erreurs de conversion des nombres : par ex, les chiffres 2 et 3 vont devenir parfois 0. Et à la fin de l'excécution j'ai le message "Erreur de segmentation" alors que j'ai libéré l'espace mémoire de tout les tableaux (non vector)
    Est-ce que vous pouvez corriger l'erreur svp. Cette erreur est visible à la lecture du fichier binaire où tab1lecture[0][0]=8608, tab1lecture[1][0]=95, tab1lecture[2][0]=8608 et tab1lecture[3][0]=95.

    Code :
    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
    98
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <new>
    #include <iomanip>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    using namespace std;
     
    int main()
    {
      short nb_y=6;
      short nb_x=4;
      short nb_x_y=nb_x*nb_y;
      short i,j;
      string filetestw="testw.bin";
      std::vector< std::vector<short> > tab1(nb_x,std::vector<short> (nb_y));
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) tab1[i][j]=i+2;
      }
     
      short* tabtmp1=new short[nb_x_y];
      short k;
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++)
        {
          k=i+(j*nb_x);
    //      cout << "k=i+(j*nb_x)=" << k << endl;
          tabtmp1[k]=tab1[i][j];
        }
      }
     
    //----------------------------------------------------------------------------------------
    // Vérification du contenu de tabtmp1
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) cout << "tabtmp1[" << i << "][" << j << "]=" << tabtmp1[i+j*nb_x] << endl;
      }
    //----------------------------------------------------------------------------------------
     
    //----------------------------------------------------------------------------------------
    //Ecriture du vector dans un fichier binaire (avec fct write)
      ofstream ficher_sortie(filetestw.c_str(), ios::binary | ios::out | ios::trunc);
      if(!ficher_sortie.is_open())
      {
        cerr << "L'ouverture du fichier de sortie en écriture à echoué\n" << endl;
        exit (-1);
      }
     
      ficher_sortie.write(reinterpret_cast<const char*>(&tabtmp1),nb_x_y*sizeof(short));
      ficher_sortie.close();
      delete[] tabtmp1;
    //----------------------------------------------------------------------------------------
     
    //----------------------------------------------------------------------------------------
    //Lecture du vector dans un fichier binaire (avec fct read)
      ifstream ficher_sortie_lu(filetestw.c_str(), ios::binary | ios::in);
      if(!ficher_sortie_lu.is_open())
      {
        cerr << "L'ouverture du fichier de sortie en lecture à echoué\n" << endl;
        exit (-1);
      }
     
      short * tabtmp1lecture=new short[nb_x_y];
      ficher_sortie_lu.read(reinterpret_cast<char*>(&tabtmp1lecture),nb_x_y*sizeof(short));
      ficher_sortie_lu.close();
     
      std::vector< std::vector<short> > tab1lecture(nb_x,std::vector<short> (nb_y));
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) tab1lecture[i][j]=tabtmp1lecture[i+j*nb_x];
      }
     
    //----------------------------------------------------------------------------------------
    // Vérification du contenu de tab1lecture
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) cout << "tabtmp1lecture[" << i << "][" << j << "]=" << tabtmp1lecture[i+j*nb_x] << endl;
      }
    //----------------------------------------------------------------------------------------
     
      delete[] tabtmp1lecture;
    //----------------------------------------------------------------------------------------
     
    //----------------------------------------------------------------------------------------
    // Vérification du contenu de tab1lecture
    //  for(i = static_cast<short>(0); i < nb_x; i++)
    //  {
    //    for(j = static_cast<short>(0); j < nb_y; j++) cout << "tab1lecture[" << i << "][" << j << "]=" << tab1lecture[i][j] << endl;
    //  }
    //----------------------------------------------------------------------------------------
     
      return (0);
    }
    Resultat :
    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
     
    tabtmp1[0][0]=2
    tabtmp1[0][1]=2
    tabtmp1[0][2]=2
    tabtmp1[0][3]=2
    tabtmp1[0][4]=2
    tabtmp1[0][5]=2
    tabtmp1[1][0]=3
    tabtmp1[1][1]=3
    tabtmp1[1][2]=3
    tabtmp1[1][3]=3
    tabtmp1[1][4]=3
    tabtmp1[1][5]=3
    tabtmp1[2][0]=4
    tabtmp1[2][1]=4
    tabtmp1[2][2]=4
    tabtmp1[2][3]=4
    tabtmp1[2][4]=4
    tabtmp1[2][5]=4
    tabtmp1[3][0]=5
    tabtmp1[3][1]=5
    tabtmp1[3][2]=5
    tabtmp1[3][3]=5
    tabtmp1[3][4]=5
    tabtmp1[3][5]=5
    tabtmp1lecture[0][0]=8608
    tabtmp1lecture[0][1]=2
    tabtmp1lecture[0][2]=2
    tabtmp1lecture[0][3]=2
    tabtmp1lecture[0][4]=2
    tabtmp1lecture[0][5]=2
    tabtmp1lecture[1][0]=95
    tabtmp1lecture[1][1]=3
    tabtmp1lecture[1][2]=3
    tabtmp1lecture[1][3]=3
    tabtmp1lecture[1][4]=3
    tabtmp1lecture[1][5]=3
    tabtmp1lecture[2][0]=8608
    tabtmp1lecture[2][1]=4
    tabtmp1lecture[2][2]=4
    tabtmp1lecture[2][3]=4
    tabtmp1lecture[2][4]=4
    tabtmp1lecture[2][5]=4
    tabtmp1lecture[3][0]=95
    tabtmp1lecture[3][1]=5
    tabtmp1lecture[3][2]=5
    tabtmp1lecture[3][3]=5
    tabtmp1lecture[3][4]=5
    tabtmp1lecture[3][5]=5
    Erreur de segmentation

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Comme ça, très vite, ceci ne va pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ficher_sortie.write(reinterpret_cast<const char*>(&tabtmp1),nb_x_y*sizeof(short));
    Remplace par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ficher_sortie.write(reinterpret_cast<const char*>(tabtmp1),nb_x_y*sizeof(short));
    Et pareil pour la lecture.

  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 camboui Voir le message
    Comme ça, très vite, ceci ne va pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ficher_sortie.write(reinterpret_cast<const char*>(&tabtmp1),nb_x_y*sizeof(short));
    Remplace par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ficher_sortie.write(reinterpret_cast<const char*>(tabtmp1),nb_x_y*sizeof(short));
    Et pareil pour la lecture.
    Effectivement "Comme ça très vite" tu as trouvé
    MERCI !
    Mais je voudrais comprendre correctement quelque chose à ce sujet du coup :
    * D'une part, j'ai repris l'exemple du tuto http://cpp.developpez.com/faq/cpp/?p...ERS_read_write --> Partie "Comment effectuer des lectures / écritures binaires dans un fichier ?"
    où j'ai lu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ...
    int xout = 24;
    FileOut.write(reinterpret_cast<const char*>(&xout), sizeof(int));
    ...
    int xin;
    FileIn.read(reinterpret_cast<char*>(&xin), sizeof(int));
    ...
    Dans ce code, pourquoi on a l'air d'écrire l'adresse de la variable et est-ce bien correct car c'est ce que je faisais (ou peut-être est-ce une impression car je manipule un tableau au lieu d'une variable)

    * Deuxièmement, comme je ne trouvais pas mon erreur, j'ai essayé d'écrire mon vecteur dans un fichier avec une autre approche : j'écris les éléments du vecteur 2D un par un à l'aide de 2 boucles. Et le code ci-dessous me donne un résultat correct alors que j'utilise les lignes :
    ..
    ficher_sortie.write(reinterpret_cast<const char*>(&tab1[i][j]),sizeof(short));
    et
    ..
    ficher_sortie_lu.read(reinterpret_cast<char*>(&tab1lecture[i][j]),sizeof(short));
    Pourquoi est-ce correct dans ce cas ?

    Code de cette solution qui fonctionne :
    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
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <new>
    #include <iomanip>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    using namespace std;
     
    int main()
    {
      short nb_y=6;
      short nb_x=4;
      short nb_x_y=nb_x*nb_y;
      short i,j;
      string filetestw="testw.bin";
      std::vector< std::vector<short> > tab1(nb_x,std::vector<short> (nb_y));
     
    //----------------------------------------------------------------------------------------
    // Remplissage du vecteur tab1
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) tab1[i][j]=i+44;
      }
    //----------------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------------
    // Vérification du contenu de tab1
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) cout << "tab1[" << i << "][" << j << "]=" << tab1[i][j] << endl;
      }
    //----------------------------------------------------------------------------------------
     
    //----------------------------------------------------------------------------------------
    //Ecriture du vector dans un fichier binaire (avec fct write)
      ofstream ficher_sortie(filetestw.c_str(), ios::binary | ios::out | ios::trunc);
      if(!ficher_sortie.is_open())
      {
        cerr << "L'ouverture du fichier de sortie en écriture à echoué\n" << endl;
        exit (-1);
      }
     
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) ficher_sortie.write(reinterpret_cast<const char*>(&tab1[i][j]),sizeof(short));
      }
      ficher_sortie.close();
    //----------------------------------------------------------------------------------------
     
    //----------------------------------------------------------------------------------------
    //Lecture du vector dans un fichier binaire (avec fct read)
      ifstream ficher_sortie_lu(filetestw.c_str(), ios::binary | ios::in);
      if(!ficher_sortie_lu.is_open())
      {
        cerr << "L'ouverture du fichier de sortie en lecture à echoué\n" << endl;
        exit (-1);
      }
     
      std::vector< std::vector<short> > tab1lecture(nb_x,std::vector<short> (nb_y));
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) ficher_sortie_lu.read(reinterpret_cast<char*>(&tab1lecture[i][j]),sizeof(short));
      }
      ficher_sortie_lu.close();
    //----------------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------------
    // Vérification du contenu de tab1lecture
      for(i = static_cast<short>(0); i < nb_x; i++)
      {
        for(j = static_cast<short>(0); j < nb_y; j++) cout << "tab1lecture[" << i << "][" << j << "]=" << tab1lecture[i][j] << endl;
      }
    //----------------------------------------------------------------------------------------
     
      return (0);
    }
    Dernièrement, je vois que tu t'y connais alors ton avis m'intéresses bcp pour cette question : quelle est la meilleur solution d'après toi. La dernière ? (voire une autre)

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    C'est clair qu'accéder aux fichiers par bloc est toujours mieux que par petit morceaux. Ta première solution avec la correction sémantique que j'ai proposé est très bien.

    Pour des explications sur les variables, adresses, pointeurs, références, tableaux, etc, je suis un piètre pédagogue

  5. #5
    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 camboui Voir le message
    C'est clair qu'accéder aux fichiers par bloc est toujours mieux que par petit morceaux. Ta première solution avec la correction sémantique que j'ai proposé est très bien.
    OK merci

    Citation Envoyé par camboui Voir le message
    Pour des explications sur les variables, adresses, pointeurs, références, tableaux, etc, je suis un piètre pédagogue
    Je comprends a peu près la raison du bug que j'avais.

    Merci pour tout.
    Bonne journée

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

Discussions similaires

  1. Problème lecture écriture par bloc dans un fichier
    Par scary dans le forum Débuter
    Réponses: 5
    Dernier message: 22/04/2009, 19h28
  2. C++ lecture d'un tableau dans un fichier
    Par nicoss dans le forum C++
    Réponses: 1
    Dernier message: 28/05/2006, 10h26
  3. Réponses: 4
    Dernier message: 12/10/2005, 21h22
  4. [JList] Lecture des données sauvegardées dans un fichier
    Par Myogtha dans le forum Composants
    Réponses: 7
    Dernier message: 10/06/2004, 21h05
  5. [C#] [.NET] Lecture d'une classe dans un fichier
    Par niPrM dans le forum Windows Forms
    Réponses: 4
    Dernier message: 18/05/2004, 08h57

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