Partage
  • Partager sur Facebook
  • Partager sur Twitter

Bug lors d'une écriture dans un fichier en mode binaire

Sujet résolu
    12 novembre 2007 à 16:14:55

    Salut à tous!
    A l'execution, cette méthode fait buguer mon projet:
    1. void Map::SaveMap()
    2. {
    3.     m_nbr_chipset = 1;
    4.     ofstream fichier("save.map", ios::out | ios::trunc);
    5.     fichier.write((char*)m_nbr_chipset,sizeof(int));
    6.     fichier.close();
    7.     free(fichier);
    8. }


    m_nbr_chipset est un int attribut de la classe Map, et même si je le remplace par une variable déclarée localement dans cette méthode, le programme plante.
    Des suggestions?

    • Partager sur Facebook
    • Partager sur Twitter
      12 novembre 2007 à 16:18:17

      Tu veux écrire en binaire allors que tu n'as même pas ouvert ton fichier en mode binaire.
      • Partager sur Facebook
      • Partager sur Twitter
        12 novembre 2007 à 16:23:27

        salut : tu caste ton attribut en char*, je ne comprend pas pourquoi tu fais ca mais c'est un mauvaise idée.


        FILE * pFile = fopen ( "fichier.dat" , "wb" );
        fwrite (&m_nbr_chipset, sizeof(int) , 1 , pFile );
        fclose (pFile);


        source et exemples : http://www.cplusplus.com/reference/clibrary/cstdio/fwrite.html
        • Partager sur Facebook
        • Partager sur Twitter
          12 novembre 2007 à 16:32:01

          Citation : gogeta1

          Tu veux écrire en binaire allors que tu n'as même pas ouvert ton fichier en mode binaire.

          En remplacant: " ios::out | ios::trunc "
          par: " ofstream::binary "
          Le programme bug toujours.

          Citation : ledemonboiteux

          salut : tu caste ton attribut en char*, je ne comprend pas pourquoi tu fais ca mais c'est un mauvaise idée.


          FILE * pFile = fopen ( "fichier.dat" , "wb" );
          fwrite (&m_nbr_chipset, sizeof(int) , 1 , pFile );
          fclose (pFile);


          source et exemples : http://www.cplusplus.com/reference/clibrary/cstdio/fwrite.html



          1°) Ce que tu me montres, c'est du C.
          2°) En C++, la méthode write n'accepte que des arguments en char*.
          Si j'enlève le (char*), ca me donne:
          1. map.cpp:: In member function `void Map::SaveMap()':
          2. map.cpp:246: error: invalid conversion from `int' to `const char*'
          3. map.cpp:246: error:   initializing argument 1 of `std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::write(const _CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]'
          4. :: === Build finished: 2 errors, 0 warnings ===
          D(ou la nescessité du (char*) .
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            12 novembre 2007 à 16:56:55

            C'est pas ios::bin?

            Pour écrire des char* comme ça je ne sais pas si c'est trop sûr. Je passerais par un sstream puis un .str() suivit de .c_str() [de std::string].
            • Partager sur Facebook
            • Partager sur Twitter
              12 novembre 2007 à 17:09:46

              Citation : hiura

              C'est pas ios::bin? [de std::string].


              1. map.cpp:: In member function `void Map::SaveMap()':
              2. map.cpp:244: error: `bin' is not a member of `std::ios' 
              3. :: === Build finished: 1 errors, 1 warnings ===



              Citation : hiura

              Pour écrire des char* comme ça je ne sais pas si c'est trop sûr. Je passerais par un sstream puis un .str() suivit de .c_str() [de std::string].



              Je veux bien, mais peux-tu expliciter?
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                12 novembre 2007 à 17:34:16

                Salut,

                pour l'ouverture c'est comme ça :

                1. ofstream fichier("fichier.txt", ios::binary);


                Ensuite, pour l'écriture, c'est :

                1. m_nbr_chipset = 1;
                2. fichier.write((char*)&m_nbr_chipset, sizeof(int));


                Il faut donner l'adresse en mémoire ou est stocké l'élémént (c'est pour ça le & )
                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  12 novembre 2007 à 17:40:01

                  Désolé j'ai oublié le 'ary'...
                  Pour l'ouverture :
                  1. ofsteam o("fchier", ios::binary);


                  Pour la conversion :
                  1. std::stringstream ss;
                  2. ss << m_nbr_chipset;
                  3. char* cchar;
                  4. strcpy(ss.str().c_str(), cchar);

                  Sauf erreur de ma part.

                  GRILLED mais post quand même. :-°
                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 novembre 2007 à 17:42:35

                    Ok, je viens de tester ce bout de code:

                    1. void Map::SaveMap()
                    2. {
                    3.     int t = 15;
                    4.     ofstream fichier("save.map", ios::binary);
                    5.     fichier.write((char*)&t,sizeof(int));
                    6.     fichier.close();
                    7.     free(fichier);
                    8.     ifstream fichier2("save.map", ios::binary);
                    9.     int a;
                    10.     fichier2.read((char*)&a,sizeof(int));
                    11.     exit(a);
                    12. }


                    Et ca marche, ca retourne bien 15.
                    Merci, Xav57!
                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 novembre 2007 à 18:00:38

                      Citation : hiura

                      Pour la conversion :

                      1. std::stringstream ss;
                      2. ss << m_nbr_chipset;
                      3. char* cchar;
                      4. strcpy(ss.str().c_str(), cchar);


                      Sauf erreur de ma part.



                      Erreur de ta part! si son nombre contient 1 ou il ne veux pas stocké "1" mais ça valeur en binaire soit "0x01" codé sur sizeof( int ) (souvent 4 octets)...

                      Tu vas me dire mieux vaut stocker "1" sur un octect que 0x01 sur 4 octets : non imagine 65000 c'est plus d'octet pour la chaîne et en plus on doit conserver la longeur de cette chaîne quelque part ou un moyen de délimiter cette chaîne. Résultat : on se retrouve rapidement avec un plus grande taille qu'un int

                      P.S. je préfère utiliser des static_cast que les cast de type C
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        12 novembre 2007 à 18:07:06

                        @Mattex, merci de me corriger! ;)
                        Je proposait ça car j'avais en tête ceci :
                        1. template<typename T> std::string ttos(T t)
                        2.     {
                        3.        std::stringstream ss;
                        4.        std::string s;
                        5.        ss << t;
                        6.        ss >> s;
                        7.        return s;
                        8.     }

                        Est-ce une mauvais technique?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 novembre 2007 à 19:55:34

                          Non si ton but est de convertir un int en chaîne de caractère mais ici on veut conserver un nombre dans un fichier en binaire alors non ce n'est pas efficace car comme je l'ai dit, si l'on veut conserver plus d'une même valeur de suite dans un même fichier l'utilisation des chaînes de caratères est lourdes et l'ont doit les séparer d'une manière où d'une autre...
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            12 novembre 2007 à 20:09:20

                            Merci de ces précisions!
                            • Partager sur Facebook
                            • Partager sur Twitter
                              12 novembre 2007 à 20:53:20

                              Ok, merci a tous, sujet Résolu
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Bug lors d'une écriture dans un fichier en mode binaire

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown