001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<string.h>
004: 
005: struct studente
006: {
007:   char matricola[11];
008:   char cognome[64];
009:   char nome[64];
010:   int n_esami;
011:   int voti[24];
012: };
013: 
014: int leggi_studente(FILE *fp, struct studente *dest)
015: {
016:   int reto=fscanf(fp, " %s %s %s %d", dest->matricola, dest->cognome, dest->nome, &dest->n_esami);
017:   if(reto != 4) return 0;
018: 
019:   int i;
020:   for(i=0; i < dest->n_esami; ++i)
021:   {
022:     fscanf(fp, "%d", &dest->voti[i]);
023:   }
024: 
025:   return 1;
026: }
027: 
028: void salva_studente(FILE *fp, const struct studente *src)
029: {
030:   fprintf(fp, "%s\t%s\t%s\t%d\t", src->matricola, src->cognome, src->nome, src->n_esami);
031:   int i;
032:   for(i=0; i < src->n_esami; ++i)
033:   {
034:     fprintf(fp, " %d", src->voti[i]);
035:   }
036:   fprintf(fp,"\n");
037: }
038: 
039: void salva_studenti(FILE *fp, const struct studente *src, const int dim)
040: {
041:   int i;
042:   for(i=0; i<dim; ++i)
043:   {
044:     salva_studente(fp, &src[i]); 
045:   }
046: }
047: 
048: int compara_studenti(const struct studente *a, const struct studente *b)
049: {
050:   //printf("Comparo %s (%s) e %s (%s) e restituisco %d\n", a->matricola, a->cognome,  b->matricola, b->cognome,  !strcmp(a->matricola, b->matricola)); // DEBUG
051:   return !strcmp(a->matricola, b->matricola);
052: }
053: 
054: struct studente *leggi_file(const char *filename, int *dim)
055: {
056:   struct studente tmp;
057:   *dim=0;
058:   struct studente *studenti=NULL;
059: 
060:   FILE *fp=fopen("elenco.txt", "r");
061:   if(!fp)
062:   {
063:     perror("");
064:     exit(EXIT_FAILURE);
065:   } 
066: 
067:   while(leggi_studente(fp, &tmp))
068:   {
069:     ++(*dim);
070:     studenti=realloc(studenti, *dim * sizeof(struct studente));
071:     if(!studenti)
072:     {
073:       perror("");
074:       exit(EXIT_FAILURE);
075:     }
076:     studenti[*dim-1] = tmp; // non ho puntatori e posso copiare cosi'
077:   }
078:   fclose(fp);
079:   return studenti;
080: }
081: 
082: int studenti_diversi(const struct studente *studenti, const int dim)
083: {
084:   int diversi=0;
085:   //int stampo;
086: 
087:   // scorro l'array e per ogni studente guardo se ce ne sono di successivi differenti, se cosi' e' non conto quella riga
088:   int i, j;
089:   for(i=0; i<dim; ++i)
090:   {
091:     ++diversi; // ipotizzo che non ce ne siano di uguali dopo
092:     for(j=i+1; j<dim; ++j) // scandisco i successivi
093:     {
094:       if(compara_studenti(&studenti[i], &studenti[j])) // guardo se e' uguale a quello in esame
095:       {
096:   --diversi; // si' allora non lo dovevo contare
097:   stampo=0;
098:   break; // e non vado oltre nel confronto
099:       }
100:     }
101:   }
102:   return diversi;
103: }
104: 
105: struct studente* pulisci_studenti(const struct studente *studenti, const int dim, int *ndim)
106: {
107:   *ndim=studenti_diversi(studenti, dim);
108:   struct studente *n_studenti=malloc(*ndim * sizeof(struct studente));
109:   if(!n_studenti)
110:   {
111:     perror("");
112:     exit(EXIT_FAILURE);
113:   }
114:   int w; // lo uso per indicare la posizione di salvataggio nel nuovo array
115:   int i, j; // come per la funzione precedente
116:   int devosalvare; // flag per capire se e' l'ultima riga
117:   for(w=0, i=0; i<dim; ++i)
118:   {
119:     devosalvare=1; // ipotizzo che non ce ne siano di uguali dopo
120:     for(j=i+1; j<dim; ++j) // scandisco i successivi
121:     {
122:       if(compara_studenti(&studenti[i], &studenti[j])) // guardo se e' uguale a quello in esame
123:       {
124:   devosalvare=0; // si' allora non lo dovevo contare
125:   break; // e non vado oltre nel confronto
126:       }
127:     }
128:     if(devosalvare)
129:     {
130:       n_studenti[w] = studenti[i]; // copio dati
131:       ++w; // aggiorno indice di scrittura
132:     }
133:   }
134:   return n_studenti;
135: }
136: 
137: int main(int argc, char **argv){
138: 
139:   struct studente *studenti; // array in cui memorizzo gli studenti
140:   int n_studenti; // e quanti somo
141: 
142:   studenti = leggi_file("elenco.txt", &n_studenti);
143: 
144:   //int n_diversi=studenti_diversi(studenti, n_studenti);
145: 
146:   int n_singoli;
147:   struct studente *ripulito=pulisci_studenti(studenti, n_studenti, &n_singoli);
148: 
149:   printf("Ho %d studenti memorizzati nel file e sono:\n", n_singoli);
150:   salva_studenti(stdout, ripulito, n_singoli); // stdin e' un FILE* e quindi per stampare a video va benissimo
151: 
152:   fp=fopen("ripulito.txt", "w");
153:   if(!fp)
154:   {
155:     perror("");
156:     exit(EXIT_FAILURE);
157:   }
158:   salva_studenti(fp, ripulito, n_singoli); 
159:   fclose(fp);
160: 
161:   free(studenti);
162:   free(ripulito);
163: 
164: 
165:   return 0;
166: }
167: 
168: