[C++] Accesso a file

Messaggioda 3m0o » 20/12/2018, 02:04

Un'università possiede la lista di tutti gli studenti memorizzata su un solo file. A ciascun studente sono attribuite diverse informazioni: numero d'identificazione, cognome, nome, data di nascita, indirizzo, sezione, ciclo di studio. Per ciascun studente le informazioni sono memorizzate linea per linea nel formato seguente sul file:
ID
<numero d'identificazione>
LASTNAME
<cognome>
FIRSTNAME
<nome>
ADDRESS
<indirizzo>
BIRTHDATE
<data di nascita>
SECTION
<sezione>
LEVEL
<ciclo di studio>
###

Dove "###" è un separatore (di fine) che c'è tra i differenti studenti. NB: le coppie di linee (etichetta,valore) possono essere in un ordine qualunque.
Ad esempio
ID
12345
LASTNAME
Doe
ADDRESS
Av. du Mail 12, 1205 Geneve
SECTION
Matematica
BIRTHDATE
1982 07 25
FIRSTNAME
John
LEVEL
PHD
###

1) Definire i tipi di dati che ti permettono di gestire tali informazioni.
2) Scrivere il prototipo e il corpo della funzione chiamata "load" che permette di caricare in memoria la lista degli studenti, a partire dal nome del file.

È fortemente consigliato di utilizzare un approccio modulare, in particolare per tutto quello che concerne gli accessi al file. Non è domandato di scrivere il codice di vostre, eventuali, sotto-funzioni ma semplicemente di spiegare in una linea di commento cosa fanno.

3) Scrivere il prototipo e il corpo della funzione "pourcentage" che ritorna la percentuale di studenti di studenti di una sezione e di un ciclo di studi passati in parametro alla funzione, rispetto alla popolazione totale di studenti (già caricata in memoria).

Vi domandiamo di scrivere il codice completo (niente modularizzazione)

Per il punto 1) io ho fatto così
Codice:


struct studente{
string id;
string cognome;
string nome;
string indirizzo;
string data;
string sezione;
string ciclo;
};


Per il punto 2)
Avrei un paio di domande, non capisco bene cosa voglia dire salvare in memoria. E dunque se la funzione "load" debba ritornare qualcosa, credo comunque di no, e inoltre non so se la concezione del programma è corretta, cosa ne pensate?
Codice:
void load(string filename){      
ifstream entrata(filename);
if(not entrata.fail()){
   string s("###");
   size_t k(lire(s,filename));
   /* la funzione "lire" prende due string in parametro, e conta quante volte è presente nel file chiamato "filename" la stringa s, e ritorna quante volte è presente! */
    vector<studente> v(k);
    for(size_t i(0); i < v.size(); i++){
          vector<string> w;

          w= ligne("LASTNAME",filename);
        /* la funzione "ligne", prende due string in parametro, e ritorna un vector di string composto dalla linea seguente alla quale ha letto "LASTNAME"  nel file di nome filename */
         
          v[i].cognome.push_back(w[i]);
          w.clear();
    
          w= ligne("FIRSTNAME",filename);
          v[i].nome.push_back(w[i]);
          w.clear();

          w= ligne("ADDRESS",filename);
          v[i].indirizzo.push_back(w[i]);
          w.clear();

          w= ligne("ID",filename);
          v[i].id.push_back(w[i]);
          w.clear();

          w= ligne("BIRTHDATE",filename);
          v[i].data.push_back(w[i]);
          w.clear();

          w= ligne("LASTNAME",filename)
          v[i].cognome.push_back(w[i]);
          w.clear();

          w= ligne("SECTION",filename)
          v[i].sezione.push_back(w[i]);
          w.clear();

          w= ligne("LEVEL",filename)
          v[i].ciclo.push_back(w[i]);
          w.clear();
      
                  }//chisura for
               }
               entrata.close();
            }



3) Per il terzo, la mia difficoltà sta nel capire come faccio a prendere gli studenti. Nel senso come faccio a recuperare il numero totale di studenti ? Sarebbe la taglia della tabella di studenti che mi sono calcolato precedentemente, il problema che la mia funzione "pourcentage" riceve in parametro una sezione e un ciclo di studi, dunque due string. Ma non ha informazione sul vector precdente, ne tanto meno ha informazione su un nome di un file da cui può prenderli.
Insomma come recupero gli studenti che sono caricati in memoria?? Poi da lì non penso di avere problemi.

Codice:
double pourcentage(string s, string cs){
vector<studenti> tot;
vector<studenti> ok;
/* in qualche modo qui recupero il vector<studenti> in memoria e la copio in "tot" */
int t(0);
int k(0);
for(size_t i(0); i < tot.size(); i++){
t+=1;
if( (tot[i].sezione == s ) and (tot[i].ciclo == cs) ){
k+=1;
}
}
double percentuale( (100*k)/t );
return percentuale;

}


Grazie per l'aiuto. :)
3m0o
Junior Member
Junior Member
 
Messaggio: 84 di 407
Iscritto il: 02/01/2018, 16:00

Re: [C++] Accesso a file

Messaggioda probid » 20/12/2018, 12:22

"non capisco bene cosa voglia dire salvare in memoria. "

inserire i dati letti nelle strutture definite al punto 1.

Codice:
   size_t k(lire(s,filename));
   /* la funzone "lire" prende due string in parametro, e conta quante volte è presente nel file chiamato "filename" la stringa s, e ritorna quante volte è presente! */


Volendo potresti passare a lire lo stream che hai già aperto, invece del nome del file; comunque non è necessario conoscere il numero degli studenti qui, nè fare una lettura completa solo per ottenerlo: poichè stai usando vector, che è una struttura dinamica, potresti espanderla man mano che leggi sequenzialmente il file.

Codice:
          w= ligne("LASTNAME",filename);
        /* la funzione "ligne", prende due string in parametro, e ritorna un vector di string composto dalla linea seguente alla quale ha letto "LASTNAME"  nel file di nome filename */
         
          v[i].cognome.push_back(w[i]);
          w.clear();


Non ho capito cosa voglia fare.
Il cognome di uno studente è unico, come mai hai definito w come un vettore? Tra l'altro v[i].cognome è una stringa, non un vector, quindi quel push_back non ha senso.
E soprattutto, come farebbe ligne ad ottenere il dato specifico per lo studente i-esimo?

Ti consiglio questo approccio:

- leggi una riga (esiste? eof);
- se è un'intestazione ti annoti cosa aspettarti subito dopo, o se è "###" aggiungi un nuovo studente;
- altrimenti valorizzi, per lo studente corrente, il campo corrispondente all'ultima intestazione letta.


Per il terzo, la mia difficoltà sta nel capire come faccio a prendere gli studenti. Nel senso come faccio a recuperare il numero totale di studenti ? Sarebbe la taglia della tabella di studenti che mi sono calcolato precedentemente


Se non puoi aggiungere il parametro, fai restituire i dati a load e chiamala all'interno di pourcentage; oppure dichiara quello che ti serve fuori dal corpo delle funzioni (variabili globali).

Ciao!

P.S: occhio che nel codice che hai scritto mi pare che sia t che ok siano inutili.
Ultima modifica di probid il 20/12/2018, 15:41, modificato 1 volta in totale.
probid
Starting Member
Starting Member
 
Messaggio: 27 di 28
Iscritto il: 01/10/2010, 20:30

Re: [C++] Accesso a file

Messaggioda 3m0o » 20/12/2018, 15:10

Intedi così?
Codice:
typedef vector<studente> tutti;


Lo faccio solo per il nome e il cognome e il numero di indetificazione per non rendere il codice lungo.
Codice:
tutti  load(string file){
ifstream entrata(file);
string s("###");
 tutti v;     
if (entrata.fail()) {
cerr << "Erreur : impossibile leggere "
<< file << endl;
}

if(not entrata.fail()){
   
    string s1("LASTNAME");
    string s2("FIRSTNAME");
    string s3("ID" );
    string s4;
 
    while(entrata)
{   
   studente a;
    if(getline(cin, s1)){
     cin >> s4;
     a.cognome=s4;
    }
    if(getline(cin, s2)){
     cin >> s4;
     a.nome=s4;
    }
    if(getline(entrata, s3)){
     cin >> s4;
     a.id=s4;
    }
    if(getline(entrata, s )){
   v.push_back(a);
    }
}
               }
               entrata.close();
               return v;
         }


Lo stesso per purcentage non capisco come faccio a prendere gli studenti, perché se chiamo "load" dentro pourcentage, quest'ultima ha bisogno dell'informazione del file, e se non posso aggiungere parametri come faccio?
3m0o
Junior Member
Junior Member
 
Messaggio: 86 di 407
Iscritto il: 02/01/2018, 16:00


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti