Newsgroup: it.comp.lang.c++
Titolo: Operazioni di I/O

Salve a tutti, il mio problema e' questo...
sto scrivendo delle strutture di dati su file in modalita' binary e fin qui
nulla di speciale...
per comodita' mi sono ridefinito un operatore per lo stream e fin qui nulla
di speciale...
chi mi sa dire perche' lo string non viene salvato correttamente ?
il compilatore non mi da errore...
posto un codice ridotto in un unico file per dare l'idea della situazione...
****************************************************
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Conto{
 private:
 char name[50];
 string surname;
 float balance;
 unsigned long account;
 public:
 void Acquisisci(void);
 void Visualizza(void);
 void Salva(void);
 void Carica(void);
 void Reset(void);
 friend ostream &operator<<(ostream &stream, Conto x);
 friend istream &operator>>(istream &stream, Conto &x);
};
void Conto::Acquisisci(void){
cin >> *this;
};
void Conto::Visualizza(void){
cout << *this;
};
void Conto::Salva(void){
  ofstream out("Status.txt", ios::app|ios::binary);
  out << *this;
  out.close();
};
void Conto::Carica(void){
  ifstream in("Status.txt", ios::binary);
  in >> *this;
  in.close();
};
void Conto::Reset(void){
  strcpy(this->name, "");
  surname = "";
  this->balance = 0;
  this->account = 0;
};
istream &operator>>(istream &stream, Conto &x){
  if(&stream == &cin){
 cout << "Inserire il nome :";
    cin >> 
x.name
;
 cout << "Inserire il cognome :";
    cin >> x.surname;
    cout << "Inserire il conto :";
 cin >> x.account;
 cout << "Inserire il bilancio :";
 cin >> x.balance;
  }else{
 stream.read((unsigned char *) &x, sizeof(Conto));
  }
  return stream;
};
ostream &operator<<(ostream &stream, Conto x){
  if(&stream == &cout){
 cout << "Nome : ";
 cout << 
x.name
 << endl;
 cout << "Cognome : ";
 cout << x.surname << endl;
 cout << "Conto : ";
 cout << x.account << endl;
 cout << "Bilancio : ";
 cout << x.balance << endl;
  }else{
 stream.write((unsigned char *) &x, sizeof(Conto));
  }
  return stream;
};
void main(void){
 Conto acc;
 cout << "Acquisisco l'oggetto" << endl;
 acc.Acquisisci();
 cout << "Salvo l'oggetto su file" << endl;
 acc.Salva();
 cout << "AZZERO l'oggetto" << endl;
 acc.Reset();
 cout << "Visualizzo l'oggetto" << endl;
 acc.Visualizza();
 cout << "Carico l'oggetto dal file" << endl;
 acc.Carica();
 cout << "Visualizzo l'oggetto caricato" << endl;
 acc.Visualizza();
 cout << "Premere x per continuare..." << endl;
 while(cin.get()!= 'x');
};
****************************************************

  ifstream in("Status.txt", ios::binary);
 ifstream in("Status.txt", ios::in | ios::binary);
--
Ciao.
Maurizio

 il compilatore non mi da errore...
E' un errore cercare di salvare e ripristinare un oggetto come std::string
copiando e riscrivendo l'area di memoria corrispondente con write() e
read(). Questa tecnica può funzionare esclusivamente con strutture POD (ma
anche in questo caso, occorre ovviamente gestire adeguatamente la
situzione in cui le strutture contengono puntatori).
La questione è stata discussa molte volte in questo NG, ad esempio:
 
http://groups.google.com/groups?th=d3222d35bdf725d8
 
http://groups.google.com/groups?th=e101b146865f4059
Max

 ha scritto nel
messaggio news:newscache$javqzg$gng$1...@listsrv01.csi.it...


naturalmente il problema non e' ios::in, ios::out...
cmq grazie

 situzione in cui le strutture contengono puntatori).
daccordissimo con i puntatori ma non del tutto con il discorso dello
string...
io posso pure accettare che i container stl non si possano salvare come
strutture intere ma sarebbe una grande boiata...
premetto che ho fatto diverse prove, ho tentato di scrivere singoli
container ma nulla da fare...
spero di aver sbagliato tecnica nella scrittura e che comunque si possa
fare...
attendo fiducioso...
Martino

 errors...
occhio a questo genere di conclusioni... ci sono degli errori nel
codice per il quale non è previsto nessun diagnostico da parte del
compilatore, che è liberissimo di non avvertirti di nulla e poi farti
esplodere il PC, il tutto nel pieno rispetto dello standard.

 fare...
Quello che vuoi fare ha un nome: "serializzazione". Ci sono diversi
approcci e tecniche, ed esiste una vasta letteratura sul tema, sia
riguardo al design, che all'implementazione in C++.
Max

 Max
Ti ringrazio della spiegazione, provero' a studiare tecniche inerenti a
quest'ultimo argomento
Martino

  stream.write((unsigned char *) &x, sizeof
x è un Conto che contiene una istanza di string.
String potrebbe essere un puntatore a qualcosa, quindi la read e la write
scrivono quel puntatore
e non la stringa contenuta! Poi in generale si ottimizza string per evitare
le copie... etc...