Newsgroup: it.comp.lang.c++
Titolo: perchè ifstream non vede l'EOF?

Giuro che non porrei questo problema se nn fossi abbastanza disperato...
Allora io praticamente una gestione di una agenda apputnamenti di un medico. 
C'ho una classe Visita, e una classe Data che uso all'interno di Visita. I 
miei oggetti Visita li memorizzo in un vector "diario". A questo punto devo 
memorizzare tutto quello che ho in un file e all'occorrenza riaprirlo ed 
estrarre il contenuto per rimetterlo nella mio "diario". La scritture va 
tutto ok. Il file è formattato bene. Quando vado al leggere però mi estrare 
solo il primo record. Il debug dice che il ciclo while trova subito dopo la 
prima estrazione la condizione while( ifs.get() != EOF ) non soddisfatta.
Metto un po' del codice... perdonatemi se è troppo...se ne serve altro per 
individuare il problema ditemelo.
Mille grazie a chi mi leva dai casini...
(ovviamente sono oltremodo bene accetti i consgli "stilistici", rimanendo 
cmq in tema di standard perchè lo so che ci sono modi migliori per gestire i 
dati... )
--
Aleander
<codice>
/* CLASSE Visita */
class Visita {
    friend std::istream& operator>>( std::istream& in, Visita& v);
    friend std::ostream& operator<<( std::ostream& out, const Visita& v);
    public:
        Visita(string n = "", string c= "", string t= "", Data r = 
Data(01,01,1900) )
        : nome(n), cognome(c), telefono(t), dataApp(r) {};
        Visita(  const Visita &v );
        char* str();  // converte un oggetto visita in uno char*
        bool operator<(Visita &v);
        string getNome() const { return nome; }
        string getCognome() const { return cognome; }
        string getTelefono() const { return telefono; }
        Data getData() const { return dataApp; }
        Visita& setNome(string n){ nome=n; return *this; }
        Visita& setCognome(string c){ cognome=c; return *this; }
        Visita& setTelefono(string t){ telefono=t; return *this; }
        Visita& setData(int g,int m,int a){ dataApp=Data(g,m,a); return 
*this; }
   // private:
        string nome;
        string cognome;
        string telefono;
        Data dataApp;
    };
// CLASSE Data
class Data{
    friend ostream& operator<<( ostream& output, const Data &d);
    friend istream& operator>>( istream& input, Data &d);
    friend class Visita;
    public:
        Data(int g=3, int m=3, int a=1903); // costruttore
        Data( const Data &d);
        Data& operator=( const Data &r );
        int getGiorno() const { return giorno; }  //funzioni di utilità get 
data
        int getMese() const { return mese; }
        int getAnno() const { return anno; }
    private:
        int giorno;
        int mese;
        int anno;
    };
FUNZIONE CHE SALVA SU FILE
template<class T>
void salva(){
    ofstream ofs("archivio.txt", ios::out);
    if (!ofs)
        cerr << "Impossibile aprire file!";
    ofs.seekp(0); // si posiziona all'inizio del file
    for (int i=0; i< diario.size(); i++){
        ofs.seekp(i*91);
        ofs.setf( ios::left );
        ofs << setw(30) << diario[i].getNome()
            << setw(30) << diario[i].getCognome()
            << setw(20) << diario[i].getTelefono()
            << diario[i].getData()
            << '\n';
    }
    ofs.close();
}
/* FUNZIONE CHE APRE IL FILE
template<class T>
void carica(){
    ifstream ifs("archivio.txt", ios::in );
    if ( !ifs ){
        cerr << "File could not be opened." << endl;
        system("PAUSE");
        mostraMenu();
    }else{
      diario.clear();
      char nom[30];
      char cog[30];
      char tel[20];
      Data data;
      int i=0;
      while( ifs.get() != EOF ){
        ifs.seekg(i*91);
        ifs >> setw(30) >> nom
            >> setw(30) >> cog
            >> setw(20) >> tel
            >> data;
        Visita buffer;
        buffer.setNome(nom);
        buffer.setCognome(cog);
        buffer.setTelefono(tel);
        buffer.setData( data.getGiorno(), data.getMese(), data.getAnno() );
        cout << "Caricato:\n" << buffer << endl;
        diario.push_back(buffer);
        i++;
      }
    }
   system("PAUSE");
}
</codice>

 condizione while( ifs.get() != EOF ) non soddisfatta.
Hai provato a verificare se si attiva il badbit e lo fa uscire da ciclo?
-- 
Cloud Strife 

       while( ifs.get() != EOF ){
Ecco... qui ti fumi il primo carattere. get estrae un carattere dallo
stream, e lo hai tolto. Ragion per cui in nom ci finiscono i caratteri
1-30 invece che 0-29, in cog idem ci finiscono 31-60 e in tel 61-80.
Bene... l'ultimo carattere succhiato dalla data (ma dovrei vedere come
fa input e output) quindi sara` in realta` il primo del nome della
seconda visita. E questo da errore.
La soluzione potrebbe:
1) ristrutturare il codice
2) usare unget come prima cosa nel ciclo.
A me poi non fa impazzire l'idea di un input output cosi` "delicato".
-- 
Adesso quando i medici di turno rifiuteranno di esserti d'aiuto / perchč
venne un polacco ad insegnargli che č piů cristiano imporsi col rifiuto
pretenderanno che tu torni indietro/e ti costringeranno a partorire per
poi chiamarlo figlio della colpa / e tu una Maddalena da pentire

 A me poi non fa impazzire l'idea di un input output cosi` "delicato".
Nemmeno a me!! Per questo fondamentalmente ho postato... Ti sarei grato se 
potessi darmi anche solo lo spunto per un metodo migliore di questo...
Sempre gentilissimo, comunque
grazie mille Enrico
--
Aleander

 tentoni!!)
Errata corrige: Mi sono accorto che gli ultimi due record presi cioè quello 
preso due volte ha il campo data con alcuni valori di default e non quelli 
effettivi...
--
Aleander 

 potessi darmi anche solo lo spunto per un metodo migliore di questo...
Mah.. puoi andare un campo per riga. E poi usare std::string invece
degli array di char.
Mario
Rossi
0522893243
10/12/2003
Siccome mi pare che comunque tu tieni tutto il file in memoria per
lavorarci, non hai grossi problemi. In compenso sei un po' piu` robusto.
-- 
Adesso quando i medici di turno rifiuteranno di esserti d'aiuto / perchè
venne un polacco ad insegnargli che è più cristiano imporsi col rifiuto
