[C++] Lecture et écriture binaire

Résolu
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 - 11 avril 2010 à 15:00
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 - 12 avril 2010 à 10:34
Bonjour, voici mon problème :

J'ai des objet que j'aimerais sauvegarder (j'ai simplifié mon code en utilisant un seul objet string) via une écriture binaire.

Je me suis rendu compte que si je pratique l'enregistrement et la lecture dans un même bloc, la lecture me renvoi bien l'objet enregistré :

int main()   
 {

//Enregistrement

ofstream fichier ("Fichier_binaire", ios::binary); //Je sais que ios::binary n'est pas utile pour du texte, mais c'est pour l'exemple...

string texte = "Texte_a_sauvegarder";

fichier.write((char*)&texte, sizeof texte);
ffichier.close();



//Lecture

ifstream fichier2 ("Fichier_binaire", ios::binary);

string texte2 = "rien";

fichier2.read ((char*)&texte2, sizeof fichier2);
fichier2.close();

cout << texte2; //ME RENVOIE BIEN "Texte_a_sauvegarder"



cout << "\n\n\n";
system("PAUSE");
     return 0;
  }


Mais dès que je sépare en deux bloc, par exemple pour demander Enregistrement ou Lecture, la lecture fonctionne pas :

 int main()
 {
cout << "1-Enregistre __ 2-Ouvre : ";
int choix;
cin >> choix;

if (choix==1)
{
//Enregistrement

ofstream fichier ("Fichier_binaire", ios::binary);

string texte = "Texte_a_sauvegarder";

fichier.write((char*)&texte, sizeof texte);
ffichier.close();

}
if (choix==2)
{
//Lecture 

ifstream fichier2 ("Fichier_binaire", ios::binary);

string texte2 = "rien";

fichier2.read ((char*)&texte2, sizeof fichier2);
fichier2.close();

cout << texte2; //ME RENVOIE "rien"
}

cout << "\n\n\n";
system("PAUSE");
     return 0;


Et pour des objets de classes que j'ai moi même créé, c'est pareil, ils ne changent pas après la lecture.

Merci de votre aide !


Pop70

2 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
12 avril 2010 à 10:21
Je suis même étonné que ça ai marché la première fois !
Tu utilises certaines notions de manières très bancales.

Pour convertir un std::string en char*, on ne prend pas son adresse ! On le convertit grâce à la méthode c_str().
Ensuite, la méthode write prend le nombre de caractères à écrire. Ça sera donc "taille du texte" + 1 (pour le zéro terminal), et non la taille de l'objet "std::string".
De plus, évite absolument les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
Une variable n'existe que dans une "portée" (toute la zone entre accolades représente une portée). Donc si tu déclares une variable à l'intérieur d'un if, celle-ci n'existe pas en dehors de celui-ci. Il n'est donc pas nécessaire de changer le nom des variables, puisqu'elles ne se "voient" pas.

Enfin, sache que si tu veux sauvegarder un objet en binaire, le mieux est de le sérialiser via Boost:serialize (cherche la bibliothèque Boost sur internet).

Ça donne ceci:
#include 
#include <fstream>

int main()
{
  std::cout << "1-Enregistre __ 2-Ouvre : ";
  int choix;
  std::cin >> choix;

  if (choix == 1)
  {
    std::ofstream fichier("Fichier_binaire", std::ios::binary);
    std::string texte = "Texte_a_sauvegarder";

    fichier.write(texte.c_str(), texte.size() + 1);
    fichier.close();
  }
  else if (choix == 2)
  {
    std::ifstream fichier("Fichier_binaire", std::ios::binary);
    char buff[256] = {0};

    fichier.read(buff, 255);
    fichier.close();
    std::string texte(buff);

    std::cout << texte << std::endl;
  }

  return 0;
}


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
3
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 10
12 avril 2010 à 10:34
Merci bien , en effet je ne m'était pas rendu compte de l'adresse du string que je prenais.
Sinon pour les using namespace , je sais que ce n'est pas à faire, et d'ailleurs dans un bouquin ils disent de le remplacer par using std::cout, using std::endl... C'est mieux ?


Pop70
0
Rejoignez-nous