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: