Salvare da file in una struct (c++)

Pubblicità
Mi sembra un po' difficile "valutare" la soluzione senza vederla, no? :rolleyes:
riporto soltanto la parte di cui si è parlato, escludendo le altre funzioni .
Per modificare la parte riguardante l'eof (perchè come mi hai spiegato non è corretto fare in quel modo, anche se non mi da nessun problema nel caso specifico) cosa mi consigli di fare?

Codice:
 #include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
    int r=0,n,i,h;                       
    char c;
    fstream openfile;
    int buffer;
    char nomefile[]="libri.txt";
    struct libro                       
       { char autore[42];
         char titolo[42];
         char editore[42];
         char genere[42];
         struct data_p
               {char giorno[6];
                char mese[6];
                int anno;
                }data;
         double prezzo;
         char pr[2];
         };

    struct libro elenco[10];
    openfile.open(nomefile,ios::in);   
    if(openfile)
      {    
       while(!openfile.eof())
       
         {             
          openfile.getline(elenco[i].autore,42,',');             
          openfile.getline(elenco[i].titolo,42,','); 
          openfile.getline(elenco[i].editore,42,','); 
          openfile.getline(elenco[i].genere,42,','); 
          openfile.getline(elenco[i].data.giorno,4,'/');
          openfile.getline(elenco[i].data.mese,4,'/');
          openfile>>elenco[i].data.anno;
          openfile>>elenco[i].prezzo;
          openfile>>elenco[i].pr;
          i++;
         }
        
     }  
    else{
       cout<<"Errore apertura file"<<endl;
       exit(1);
           }       
  openfile.close();
  system("pause");
  return 0;
}
 
Ultima modifica:
La condizione di eof viene settata solo dopo un'operazione di I/O. E' per questo che non ha senso chiamarla dopo aver aperto lo stream di input. Infatti, se anche lo stream fosse vuoto, lo stesso la condizione di eof non verrebbe settata in quanto nessuna operazione di I/O sarebbe stata effettuata. Le operazioni di I/O, come credo di averti scritto, ritornano invece lo stream stesso se !fail() (cosa che comprende anche la condizione di eof) e 0 altrimenti. Questa caratteristica è quindi sfruttabile come condizione di un ciclo per non farlo proseguire, cosa che implica anche -per un ciclo di lettura- il non utilizzare quanto si è letto se il test fallisce.
 
La condizione di eof viene settata solo dopo un'operazione di I/O. E' per questo che non ha senso chiamarla dopo aver aperto lo stream di input. Infatti, se anche lo stream fosse vuoto, lo stesso la condizione di eof non verrebbe settata in quanto nessuna operazione di I/O sarebbe stata effettuata. Le operazioni di I/O, come credo di averti scritto, ritornano invece lo stream stesso se !fail() (cosa che comprende anche la condizione di eof) e 0 altrimenti. Questa caratteristica è quindi sfruttabile come condizione di un ciclo per non farlo proseguire, cosa che implica anche -per un ciclo di lettura- il non utilizzare quanto si è letto se il test fallisce.
ho capito quanto mi hai scritto, il problema però è che in questo caso non posso utilizzare un'operazione di input/output come condizione di un ciclo perché non saprei come scrivere altrimenti quella serie di operazioni in lettura.
Comunque, sono sicuro che il file in lettura non sia vuoto, di conseguenza quella condizione (anche se come mi hai detto è concettualmente sbagliata), non mi da nessun problema.
Per quanto riguarda il valore ritornato dalle operazioni di I/O non mi è chiaro cosa intendi però quando dici ritornano lo stream stesso se !fail(). (da un punto di vista pratico)
Intendi che in un'operazione di lettura (ad es openfile.getline() dove openfile è un fstream) ritorna quanto letto con quell'operazione?
 
Ultima modifica:
Bene, visto che non ti da nessun problema non starò a spiegarti perché è importante scrivere programmi che siano logicamente corretti a prescindere dal fatto che funzionino o meno :)
Riguardo il ciclo, puoi sfruttare il fatto che i campi sono ordinati e quindi puoi usare uno switch con un contatore per selezionare su quale campo scrivere testando alla fine lo stream.

Codice:
int field = 0;
do {
  switch(field++) {
    case 0: openfile.getline(elenco[i].autore,42,','); break;
    case 1: ...
    case 2: ...
    case ....
    case 6: openfile>>elenco[i].data.anno; break;
    case ...
  }
  if (field > 8) {
    field = 0;
    ++i;
  }
} while(openfile);
//se field <= 8 c'è stato qualche problema e l'ultimo record non è valido

Non ho fatto verifiche, ma concettualmente dovrebbe funzionare.
 
Pubblicità
Pubblicità
Indietro
Top