File binari

di il
4 risposte

File binari

Salve a tutti. Eccomi di nuovo qui dopo un po' di tempo pronto con nuovi dubbi e nuove domande. Dovrei risolvere un esercizio piuttosto lunghetto e avrei bisogno di un aiuto. Ho buttato giù del codice ma mi sa che dev'essere rivisto. Per comodità le funzioni membro delle classi le ho sviluppate in linea. La traccia completa è a questo indirizzo:
http://www.mediafire.com/?mq31daap7bp9hq
Il codice che ho provato a scrivere è parziale e vorrei dritte su come muovermi. Grazie

#include <iostream>

using namespace std;

class Error 
{ 
      private:
              char* msg; 
      public: 
              Error(char* _msg) : msg(new char[strlen(_msg)+1]) { strcpy(msg,_msg); }
              ~Error() { delete [] msg; } 
              char* what() { return msg; } 
};

class Libro
{
      private:
              char *autori;
              char *titolo;
              int anno;
      public:
              Libro (char *Autori="", char *Titolo="", int Anno=0) : autori(new char[strlen(Autori)+1]), titolo(new char[strlen(Titolo)+1]), anno(Anno)
              {
                    strcpy(autori,Autori);
                    strcpy(titolo,Titolo);
              }
              ~Libro() { delete [] autori; delete [] titolo; }
              char* get_autori() { return autori; }
              char* get_titolo() { return titolo; }
              int get_anno() { return anno; }
              void stampa()
              {
                   cout << "Autore: " << autori << endl;
                   cout << "Titolo: " << titolo << endl;
                   cout << "Anno: " << anno << endl << endl;
              }
              friend ifstream& operator >> (ifstream& file, Libro& libro) throw (Error)
              {
                     file.open("Output.txt", ios::in);
                     if(!file)
                     {
                              Error *er = new Error ("\nApertura in lettura non riuscita\n");
                              throw er;
                     }
                     else
                     {
                              file >> libro.autori;
                              file >> libro.titolo;
                              file >> libro.anno;
                     }
                     file.close();
                     return file;
              }
              
              friend ofstream& operator << (ofstream& file, Libro& libro) throw (Error)
              {
                     file.open("Output.txt", ios::out);
                     if(!file)
                     {
                              Error *er = new Error ("\nApertura in scrittura non riuscita\n");
                              throw er;
                     }
                     else
                     {
                              file << "Autore: " << libro.autori << endl;
                              file << "Titolo: " << libro.titolo << endl;
                              file << "Anno: " << libro.anno << endl << endl;
                     }
                     file.close();
                     return file;
              }
};

class Lista 
{
      class Nodo 
      { 
            public: 
                    Libro* l; 
                    Nodo* next; 
                    Nodo(Libro* _l=0, Nodo* _n) : l(_l), next(_n) {}; 
                    ~Nodo(){}; 
      }; 
                    
      private:
              Nodo* head; 
      public: 
              Lista(Nodo* _n=0): head(_n) {}; 
              Lista(char *fname);
              ~Lista()
              {
                      Nodo *temp=head;
                      while(temp!=0)          //Scorre tutta la lista...
                      {
                         head=head->next;          //...facendo scorrere in avanti first
                         delete temp;                //e cancellando il precedente,
                         temp=head;                 //fino all'ultimo elemento.
                      }
              } 
              void inserisci(Libro* l)
              {
                   Nodo *p = new Nodo(l,0);
                   if(head != 0)
                   {
                           p->l=l;
                           p->next = head;
                           head = p;
                   }
                   else head = p;
              } 
              void salva(char *fname) throw (Error)
              {
                   ofstream file (fname, ios::out);
                   Nodo *temp = head;
                   while(temp!=0)
                   {
                                 file << temp->l;
                   } 
                   file.close();
              }
                    
              void stampa()
              {
                   Nodo *temp = head;
                   while(temp!=0)
                   {
                      temp=temp->next;       
                   }
              }   
};
Il main è fornito dalla traccia. L'ho provato almeno sulla funzione inserisci ma non funziona. POi magari vorrei se qualcuno ne è in possesso di un buon link chiaro ed esauriente sulla gestione dei file soprattutto binari in c++.

4 Risposte

  • Re: File binari

    Se il file è in binario una cosa che non ho vista è l'apertura in binario e cioè: ios::binary.
    Se non lo vuoi usare devi mettere un deliminatore di campo se no quando leggi, leggerai i dati male. Il resto a dir la verità non l'ho guardato.
    Quì hai qualcosa sul I/O dei file anche in binario.
    http://www.cplusplus.com/doc/tutorial/files
  • Re: File binari

    Skynet non è che hai tempo di guardare il codice e darmi delle dritte su come fare, errori ecc a parte la questione ios::binary...Grazie
  • Re: File binari

    Controlla un pò le modifiche e chiedi se non capisci qualcosa.
    
    #include <iostream>
    #include <fstream>
    #include <exception>
    
    using namespace std;
    
    class Error
    {
    private:
    	char* msg;
    public:
    	Error(char* _msg) : msg(new char[strlen(_msg)+1]) { strcpy(msg,_msg); }
    	Error(const Error & rhs)
    	{
    		msg = new char[strlen(rhs.msg) + 1];
    		strcpy(msg,rhs.msg);
    	}
    	~Error() { delete [] msg; }
    	char* what() { return msg; } 
    };
    
    class Libro
    {
    private:
    	char *autori;
    	char *titolo;
    	int anno;
    public:
    	Libro (char *Autori="", char *Titolo="", int Anno=0) : autori(new char[strlen(Autori)+1]), titolo(new char[strlen(Titolo)+1]), anno(Anno)
    	{
    		strcpy(autori,Autori);
    		strcpy(titolo,Titolo);
    	}
    	~Libro() { delete [] autori; delete [] titolo; }
    	char* get_autori() { return autori; }
    	char* get_titolo() { return titolo; }
    	int get_anno() { return anno; }
    	void stampa()
    	{
    		cout << *this;
    	}
    	friend istream& operator >> (istream& file, Libro& libro) throw (Error)
    	{
    		if(!file)
    		{
    			throw Error("\nApertura in lettura non riuscita\n");
    		}
    		else
    		{
    			char *temp = new char[256];
    			if(file.getline(temp,256))
    			{
    				char * ptr = strstr(temp,"Autore: ");
    				if(ptr)
    				{
    					ptr += 8;
    					libro.autori = new char[strlen(ptr) + 1];
    					strcpy(libro.autori,ptr);
    				}
    				file.getline(temp,256);
    				ptr = strstr(temp,"Titolo: ");
    				if(ptr)
    				{
    					ptr += 8;
    					libro.titolo = new char[strlen(ptr) + 1];
    					strcpy(libro.titolo,ptr);
    				}
    				file.getline(temp,256);
    				ptr = strstr(temp,"Anno: ");
    				if(ptr)
    				{
    					ptr += 6;
    					libro.anno = atoi(ptr);
    				}
    				delete [] temp;
    			}
    		}
    		return file;
    	}
    	friend ostream& operator << (ostream& file, const Libro& libro) throw (Error)
    	{
    		if(!file)
    		{
    			throw Error("\nApertura in scrittura non riuscita\n");
    		}
    		else
    		{
    			file << static_cast<const char *>("Autore: ") << libro.autori << endl;
    			file << static_cast<const char *>("Titolo: ") << libro.titolo << endl;
    			file << static_cast<const char *>("Anno: ") << libro.anno << endl;
    		}
    		return file;
    	}
    };
    
    
    class Lista
    {
    	class Nodo
    	{
    	public:
    		Libro* l;
    		Nodo* next;
    		Nodo(Libro* _l=0, Nodo* _n=0) : l(_l), next(_n) {};
    		~Nodo(){};
    	};
    
    private:
    	Nodo* head;
    public:
    	Lista(Nodo* _n=0): head(_n) {};
    	Lista(char *fname)
    	{
    		head = 0;
    		ifstream file(fname, ios::in);
    		Libro *l = new Libro();
    		while(file >> *l)
    		{
    			inserisci(l);
    			l = new Libro();
    		}
    		delete l;
    		file.close();
    	};
    	~Lista()
    	{
    		Nodo *temp=head;
    		while(temp!=0)          //Scorre tutta la lista...
    		{
    			head=head->next;          //...facendo scorrere in avanti first
    			delete temp;                //e cancellando il precedente,
    			temp=head;                 //fino all'ultimo elemento.
    		}
    	}
    	void inserisci(Libro* l)
    	{
    		Nodo *p = new Nodo(l,0);
    		if(head != 0)
    		{
    			p->l=l;
    			p->next = head;
    			head = p;
    		}
    		else
    		{
    			p->next = 0;
    			head = p;
    		}
    	}
    	void salva(char *fname) throw (Error)
    	{
    		try
    		{
    			ofstream file (fname, ios::out);
    			Nodo *temp = head;
    			while(temp!=0)
    			{
    				file << *(temp->l);
    				temp = temp->next;
    			}
    			file.close();
    		}
    		catch(Error & e)
    		{
    			throw;
    		}
    	}
    
    	void stampa()
    	{
    		Nodo *temp = head;
    		while(temp!=0)
    		{
    			temp->l->stampa();
    			temp=temp->next; 
    		}
    	}   
    };
    
    int main() 
    { 
    	Lista l1; /* crea una lista vuota */ 
    	Libro* libro;
    	libro = new Libro("Lev Tolstoj", "Guerra e pace", 1865); 
    	l1.inserisci(libro); 
    	libro = new Libro("Giovanni Verga", "I Malavoglia", 1881); 
    	l1.inserisci(libro); 
    	cout << "Contenuto di l1:" << endl; 
    	l1.stampa(); 
    	try 
    	{ 
    		l1.salva("libri.dat"); /* salva su file */ 
    	} 
    	catch (Error & e) 
    	{ 
    		cout << e.what() << endl; 
    	} 
    	Lista l2("libri.dat"); 
    	libro = new Libro("Walter Scott", "Ivanhoe", 1819); 
    	l2.inserisci(libro); 
    	cout << "Contenuto di l2:" << endl; 
    	l2.stampa(); 
    }
    
    Il prof non usa il keyword const vedo, e sta cosa non è un bene. Non so chi ha fatto la classe Error ma la fatto male. La classe deve avere il costruttore di copia se no il catch cattura casini.
    Leggi sto paragrafo:

    specialmente il 17.17
    Objects that are thrown must have a publicly accessible copy-constructor. The compiler is allowed to generate code that copies the thrown object any number of times, including zero. However even if the compiler never actually copies the thrown object, it must make sure the exception class's copy constructor exists and is accessible.
    Ma lo sa il prof che esiste la classe string, ancora con i char * continua?
  • Re: File binari

    Tutto chiaro skynet grazie.
Devi accedere o registrarti per scrivere nel forum
4 risposte