PDA

Visualizza la versione completa : [C++] Overloading operatori di shift per file binario


alukard990
20-01-2012, 20:06
Salve a tutti stavo realizzando un programma che vuole gestire i dati relativi ad un libro; i dati sono: autore(char*),titolo(char*) e anno(int). Oltre ai costruttori e distruttori e alle funzioni get si vogliono realizzare l'oveloading degli operatori di shift ( << e >>) per l'inserimento e la lettura su file binario; Ho realizzato tutto quanto ma il programma mi crasha.Provando ad eseguire step by step forse c'è un problema nell'overloading di << ma non sono sicurissimo.Qualcuno può aiutarmi?


#ifndef LIBRO_H_
#define LIBRO_H_
#include <fstream>
#include <iostream>
#include <cstring>

using namespace std;

class libro{

private:
char* autore;
char* titolo;
int anno;

public:
libro(const char* a="",const char* t="",const int aa=0): autore(new char[strlen(a)+1]), titolo(new char[strlen(t)+1]), anno(aa) {strcpy(autore,a); strcpy(titolo,t); anno=aa;}
libro(const libro &);
~libro() {delete[] autore; delete[] titolo;}
const libro & operator=(const libro &);
const char* get_autore()const {return autore;}
const char* get_titolo()const {return titolo;}
int get_anno()const {return anno;}
friend ofstream& operator<<(ofstream&, libro&);
friend ifstream& operator>>(ifstream&,libro&);
friend ostream& operator<<(ostream&,const libro&);

};
#endif

#include "libro.h"

libro::libro(const libro & L)
{
autore=new char[strlen(L.autore)+1];
strcpy(this->autore,L.autore);
titolo=new char[strlen(L.titolo)+1];
strcpy(this->titolo,L.titolo);
anno=L.anno;
}

ofstream& operator<<(ofstream& ofs, libro& l)
{
int size=strlen(l.autore);
ofs.write(reinterpret_cast<char*>(&size), sizeof(int));
ofs.write(l.autore, size*sizeof(char));

size=strlen(l.titolo);
ofs.write(reinterpret_cast<char*>(&size), sizeof(size));
ofs.write(l.titolo, size*sizeof(char));

ofs.write(reinterpret_cast<const char*>(&l.anno),sizeof(int));
return ofs;
}

ifstream& operator>>(ifstream& ifs,libro& l)
{
int size=0;

ifs.read(reinterpret_cast<char*>(&size), sizeof(int));
ifs.read(l.autore, size*sizeof(char));

ifs.read(reinterpret_cast<char*>(&size), sizeof(int));
ifs.read(l.titolo, size*sizeof(char));

ifs.read(reinterpret_cast<char*>(&l.anno), sizeof(int));

return ifs;
}

ostream& operator<<(ostream& os,const libro & L)
{
os<<"\nAutore: " << L.autore<< "\nTitolo: "<< L.titolo << "\nAnno pubblicazione: " << L.anno <<"\n";
return os;
}
#include <cstdlib>
#include <iostream>
#include "libro.h"

using namespace std;

int main(int argc, char *argv[])
{
libro l("Dan Brown", "Il Codice da Vinci", 2005);

ofstream out("dati.dat", ios::binary);
out<<l;
out.close();

libro p;
ifstream in("dati.dat", ios::binary);
in>>p;
in.close();

cout << p;
system("PAUSE");
return 0;
}

shodan
20-01-2012, 23:43
operator << mi pare a posto.

E' operator >> che è da sistemare.
Lo spazio effettivo che l.autore possiede è al massimo 1 byte. Rivedi il costruttore.
(E non solo l.autore ovviamente)

alukard990
20-01-2012, 23:53
parli del costruttore con i parametri di default che non va?

MItaly
21-01-2012, 00:05
(per inciso, secondo me non è una buona idea fare l'overload di << e >> per IO binario - tipicamente vengono usati per IO formattato)

shodan
21-01-2012, 00:06
Si.
Se effettui una strlen() su autore in operator >> ti accorgi che vale 1.
Questo perché nel costruttore allochi memoria per una stringa vuota.
Un approccio corretto sarebbe definire un costruttore di default che azzeri i vari puntatori e togliere i parametri di default nel costruttore parametrico.
All'interno di operator >> effettui un check di validità dei puntatori (sono NULL? Non sono NULL?) e ti regoli di conseguenza.

alukard990
21-01-2012, 09:55
Per MItaly: in effetti hai ragione ma purtroppo la prof in qualche prova d'esame lo mette e quindi bisogna accontentarla :D ; per shodan: ok seguirò le tue linee guida. E comunque un grazie a tutti per la vostra disponibilità :ciauz: :)

Loading