[File C++] Visualizzazione

di il
3 risposte

[File C++] Visualizzazione

Salve programmatori e non.
Ho presentato questa mia domanda su un altro forum a cui non mi hanno risposto, purtroppo, allora cercando in rete ho trovato questo lido, spero di essere ben accolto.
Ho da poco iniziato ad esercitarmi con i file in C++, ma già ho trovato qualche problema di cui il libro che uso non riporta soluzione.
Con il seguente programma, registro in un file di testo gli abitanti di un paese utilizzando una struttura.
Mi chiedevo come si facesse a visualizzare il testo scritto in precedenza o già presente nel file all'inizio del programma e dopo aver aggiunto nuove persone.
Utilizzando il cout mi esce una sequenza che credo indichi il puntatore in memoria al file (o mi sbaglio? cosa sarebbe quella sequenza alfanumerica?)
Oltre a risolvermi il problema, mi sapreste anche spiegare il perchè col cout non funziona la visualizzazione?
Grazie.
#include <iostream>
#include <fstream>
using namespace std;

struct nascita{
       int aa, mm, gg;
};

struct dati{
       char nome[20], cognome[20];
       struct nascita data;       
};

typedef struct dati persona;

int richiesta(int sx, int dx);

int main (){
    ofstream fout("Abitanti.txt", ios::app);
    cout << fout;
    if (fout.is_open()){
       for (persona abit; ;){
           cout << "Introdurre il cognome dell'abitante (* per uscire):\n";
           cin.getline(abit.cognome, 20);
           if (abit.cognome[0]=='*') break;
           fout << abit.cognome << " ";
           cout << "Introdurre il nome di " << abit.cognome << ":\n";
           cin.getline(abit.nome, 20);
           fout << abit.nome << " ";
           cout << "Introdurre la data di nascita di " << abit.cognome 
                << " " << abit.nome << ".\n";
           cout << "Giorno: ";
           abit.data.gg=richiesta(1, 31);
           fout << abit.data.gg << "/";
           cout << "Mese:   ";
           abit.data.mm=richiesta(1, 12);
           fout << abit.data.mm << "/";
           cout << "Anno:   ";
           cin >> abit.data.aa;
           while (abit.data.aa<0){
                 cout << "L'anno inserito non è esatto, riprovare...\n";
                 cin >> abit.data.aa;
           }
           fout << abit.data.aa << "\n";
           cin.ignore();
       }
    }
    else{
    cout << "Si è verificato un errore nell'apertura del file.\n";
    }
    cout << fout;
    fout.close();
    cin.get();
    return 0;
}

int richiesta (int sx, int dx){
    int n;
    cin >> n;
    while (n<sx || n >dx) {
          cout << "Puoi inserire "; 
          if (sx==dx) cout << "solo il numero " << sx << ": ";
          else       cout << "solo numeri compresi tra " << sx << " e " << dx << ": ";
          cin >> n;
    }
    return n;
}

3 Risposte

  • Re: [File C++] Visualizzazione

    Ciao, ci sono due motivi per cui non funziona; il primo è che l'oggetto ofstream tiene memorizzato, in mododo automatico, un puntatore alla posizione corrente di scrittura nel file, poichè tu hai scritto dei dati alla fine del file, questo punta alla fine del file. Così con listruzione cout<<fout; cerci di leggere dei dati oltre la fine del file. Il secondo motivo è che l'oggetto ofstream permette solo di scrivere in un file e non di leggere.

    Per risolvere il problema puoi al posto della riga cout<<fout; chiudere il file Abitanti.txt, riabrirlo con una variabile di tipo ifstream o fstream e poi con un ciclo leggerne tutto il contenuto e stamparlo a video. L'oggetto ifstream è l'opposto di ofstream, permette solo di leggere e non di scrivere, l'oggetto fstream invece permette sia di scrivere che di leggere.
    Utilizzando il cout mi esce una sequenza che credo indichi il puntatore in memoria al file (o mi sbaglio? cosa sarebbe quella sequenza alfanumerica?)
    Secondo me il numero che ti stampa potrebbe essere casuale, visto che leggi oltre la fine del file con un oggetto che non permette la lettura chissa cosa fa.

    Ciao
  • Re: [File C++] Visualizzazione

    DPD ha scritto:


    Ciao, ci sono due motivi per cui non funziona; [...]
    Ciao
    Ciao, e grazie per la risposta, non ci speravo più...

    Cmq ho modificato, ma trovo altri problemi.
    Apro il file con l'fstream sia in input che in output con le impostazioni ios::in | ios::out | ios::ate.
    Vorrei tenere il puntatore fstream all'inizio del file, ma con la funzione open per non sovrascrivere bisogna per forza mettere ios::app o ios::ate.
    Non capisco la differenza tra i due, visto che ognuno si posizione infondo al file cmq. Però con app il file non mi si apre, e neanche qui non capisco il perchè, quindi ho scelto di usare ate.
    Quando dopo l'apertura, vado a leggere dal file i dati presenti, se ci sono vengono letti in modo non corretto. Ne deduco che abbia sbagliato qualcosa nella scrittura allora.
    Se invece nel file non c'è niente, cmq legge ugualmente, nonostante il puntatore sia alla fine del file e abbia inserito la condizione !file.eof(), che dovrebbe uscire da, o non eseguire, il ciclo for.
    Leggendo però info sulla funzione su cplusplus.com, essa verifica se è impostato il eofbit, che viene impostato quando si raggiunge la fine del file da una operazione di input. Visto che io di operazioni di input non ne ho fatte nessuna prima di verificare la condizione, il comportamento è normale.
    Quindi decido di non effettuare nessuna lettura dei dati all'apertura del programma, ma farne una intera di tutto il file alla fine dopo aver inserito nuovi dati.

    Modifico e faccio partire, inserisco i dati, ma la lettura non va.
    Mi accorgo che non può essere fatta perchè il puntatore si trova alla fine del file dopo la scrittura, quindi con seekp() posiziono il puntatore all'inizio.
    Non so proprio usare bene questa funzione, cmq deduco che se nel long che devo dare come parametro memorizzo 0, il file si va a posizionare all'inizio.
    Ma come al solito sempre niente. Anzi, c'è di peggio, alla lettura windows mi chiude l'eseguibile per un errore.

    A questo punto non ho la minima idea di come comportarmi.
    Tra l'altro sono in questa situazione non perchè, io niubbio di file non mi sia documentato su di essi, ma che ci posso fare se il libro scolastico su cui studio parla per 10 pagine di file in C e dedica solo 2 pagine a come si gestiscono in C++??
    Non ci sono degli esempi di lettura e scrittura, non ci sono degli esempi su come si utilizza la funzione seekp(), niente, c'è solo scritto l'elenco delle funzioni, come si legge e si scrive sul file (ma non come si visualizza a video), poi come si apre e chiude un file e basta.
    Su internet ho cercato sul sito cplusplus.com, ma li parla di tutto, c'è anche un tutorial, ma guarda caso, che cosa non c'è in quest'ultimo? I File.
    Ti prego anche di consigliarmi dei link utili sulla gestione dei file, soprattutto in italiano, ma vanno bene anche in inglese, grazie.
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    struct nascita{
           int aa, mm, gg;
    };
    
    struct dati{
           char nome[20], cognome[20];
           struct nascita data;       
    };
    
    typedef struct dati persona;
    
    persona abit;
    fstream file;
    
    void scrittura();
    void inserimento();
    int richiesta (int sx, int dx);
    
    int main(){
        file.open("Abitanti.txt", ios::in | ios::out | ios::ate);
        if (file.is_open()){
           inserimento();
           long pos=0;
           file.seekp(pos, ios::beg);
           cout << "Dati presenti:\n";
           scrittura();
        }
        else{
        cout << "Si e verificato un errore nell'apertura del file.\n";
        }
        file.close();
        cin.get();
        return 0;
    }
    
    void scrittura(){
         for (;!file.eof() ;){
             file >> abit.cognome;
             cout << abit.cognome << " ";
             file >> abit.nome;
             cout << abit.nome << " ";
             file >> abit.data.gg;
             cout << abit.data.gg << "/";
             file >> abit.data.mm;
             cout << abit.data.mm << "/";
             file >> abit.data.aa;
             cout << abit.data.aa << "\n";
         }
    }
    
    void inserimento(){
         for (; ;){
             cout << "Introdurre il cognome dell'abitante (* per uscire):\n";
             cin.getline(abit.cognome, 20);
             if (abit.cognome[0]=='*') break;
             file << abit.cognome;
             cout << "Introdurre il nome di " << abit.cognome << ":\n";
             cin.getline(abit.nome, 20);
             file << abit.nome;
             cout << "Introdurre la data di nascita di " << abit.cognome 
                  << " " << abit.nome << ".\n";
             cout << "Giorno: ";
             abit.data.gg=richiesta(1, 31);
             file << abit.data.gg;
             cout << "Mese:   ";
             abit.data.mm=richiesta(1, 12);
             file << abit.data.mm;
             cout << "Anno:   ";
             cin >> abit.data.aa;
             while (abit.data.aa<0){
                   cout << "L'anno inserito non è esatto, riprovare...\n";
                   cin >> abit.data.aa;
             }
             file << abit.data.aa;
             cin.ignore();
         }
    }
    
    int richiesta (int sx, int dx){
        int n;
        cin >> n;
        while (n<sx || n >dx) {
              cout << "Puoi inserire "; 
              if (sx==dx) cout << "solo il numero " << sx << ": ";
              else       cout << "solo numeri compresi tra " << sx << " e " << dx << ": ";
              cin >> n;
        }
        return n;
    }
    
    Buonanotte e grazie per ulteriori risposte.
  • Re: [File C++] Visualizzazione

    Ciao, da quello che ho capito la differenza tra ios::ate e ios::app è che il primo apre un file esistente, mentre il sencondo crea il file se questo non esite.
    L'altra volta ho dimenticato di dirti che nell'oggetto fstream ci sono due puntatori, uno alla posizione in cui cominciare a scrivere ed uno alla posizione in cui cominciare a leggere. Il primo lo si modifica col metodo seekp ed il secondo con seekg, i parametri dei metodi sono gli stessi il primo è un intero che indica la nuova posizione, in byte, a cui va messo il puntatore, l'altro può essere:
Devi accedere o registrarti per scrivere nel forum
3 risposte