/* Svolgimento compito di esame del 18-6-1999 -- Fondamenti di Informatica (Amb. e Territorio) */


#include <stdio.h>
#include <stdlib.h>

struct studente {
        char  matricola[9],
              nome[21],
              cognome[21],
              cl[5],
              dataesame[9];
        short esito,
              lode;
};

struct elem {
        short voto,
              molteplicita;
        struct elem *next;
};

/* prototipi */
                void CreaRiepilogo(char *);
                struct studente *InserisciRecord(struct studente *);
                struct elem *CostruisciPresenze(char *);
                FILE *ApriFile(char *, char *);
                void CostruisciFileMedieAlte(char *, char *);
                struct elem *CercaVoto(struct elem *, short);
                void Accoda(struct elem **, shortstruct elem **);
                struct elem *CreaElemento(short);
                void StampaLista(struct elem *);



int main()
{
        struct elem *presenze;
        char nomefile1[21], nomefile2[21];
        int scelta;
        
        printf("Salve.\n");
        do {
                printf("[C]ostruisci o [L]eggi file riepilogativo? ");
                scelta=getchar();
                getchar();
        } while((scelta!='c')&&(scelta!='C')&&(scelta!='l')&&(scelta!='L'));
        printf("Nome file? ");
        gets(nomefile1);
        if((scelta=='C')||(scelta=='c'))
                CreaRiepilogo(nomefile1);

        printf("Nome file delle medie alte? ");
        gets(nomefile2);
        CostruisciFileMedieAlte(nomefile1, nomefile2);

        presenze=CostruisciPresenze(nomefile2);
        StampaLista(presenze);

        printf("Arrivederci.\n");
        return 0;
}


void CreaRiepilogo(char *nome)
{
        FILE *f;
        struct studente record;
        f=ApriFile(nome,"wb");
        while(InserisciRecord(&record)!=NULL)
                fwrite(&record,sizeof(record),1,f);
        fclose(f);
        return;
}


struct studente *InserisciRecord(struct studente *rec)
/* restituisce rec se ha successo, NULL se non legge */
{
        printf("matricola (invio per terminare): ");
        gets(rec->matricola);
        if(rec->matricola[0]==0)
                return NULL;
        printf("nome: ");
        gets(rec->nome);
        printf("cognome: ");
        gets(rec->cognome);
        printf("cl: ");
        gets(rec->cl);
        printf("data esame: ");
        gets(rec->dataesame);
        do {
                printf("esito (da 18 a 30): ");
                scanf("%hd",&rec->esito);
                getchar();
        } while((rec->esito<18)||(rec->esito>30));
        rec->lode=0;
        if(rec->esito==30) {
                printf("lode? ");
                if(getchar()=='s')
                        rec->lode=1;
                getchar();
        }
        return rec;
}       


FILE *ApriFile(char *nomechar *modo)
{
        FILE *f;
        f=fopen(nome, modo);
        if(f==NULL) {
                fprintf(stderr,"Fallimento nell'apertura del file \"%s\" in modalita` \"%s\". Programma terminato.\n");
                exit(1);
        }
        return f;
}


void CostruisciFileMedieAlte(char *nome1char *nome2)
{
        int somma=0, conta=0, media/* ci basta la parte intera della media */
        FILE *f1, *f2;
        struct studente rec;
        
        f1=ApriFile(nome1,"rb");
        for(fread(&rec,sizeof(rec),1,f1); !feof(f1); fread(&rec,sizeof(rec),1,f1)) {
                somma += rec.esito;
                conta++;
        }
        if(conta>0)
                media=somma/conta;
        else
                printf("FIle \"%s\" vuoto!\n",nome1);
        
        f2=ApriFile(nome2, "wb");
        rewind(f1);
        
        for(fread(&rec,sizeof(rec),1,f1); !feof(f1); fread(&rec,sizeof(rec),1,f1))
                if(rec.esito>media)
                        fwrite(&rec.esito,sizeof(rec.esito),1,f2);
        
        fclose(f1);
        fclose(f2);
        return;
}


struct elem *CostruisciPresenze(char *nome)
{
        FILE *f;
        struct elem *ptesta=NULL, *pcoda, *posto;
        short voto;
        f=ApriFile(nome,"rb");
        
        for(fread(&voto,sizeof(voto),1,f); !feof(f); fread(&voto,sizeof(voto),1,f)) {
                posto=CercaVoto(ptesta,voto);
                if(posto==NULL)
                        Accoda(&ptesta,voto,&pcoda);
                else
                        posto->molteplicita++;
        }
        
        fclose(f);
        return ptesta;
}


struct elem *CercaVoto(struct elem *pshort voto)
{
        while (p!=NULL)
                if(p->voto==voto)
                        return p;
                else
                        p=p->next;
        return NULL;
}


void Accoda(struct elem **pptestashort vstruct elem **ppcoda)
{
        struct elem *nuovo;
        nuovo=CreaElemento(v);
        if(*pptesta==NULL)
                *pptesta=nuovo;
        else
                (*ppcoda)->next=nuovo;
        *ppcoda=nuovo;
        return;
}


struct elem *CreaElemento(short info)
{
        struct elem *nuovo;
        nuovo=malloc(sizeof(struct elem));
        if(nuovo==NULL) {
                fprintf(stderr, "malloc fallita. Programma terminato.\n");
                exit(2);
        }
        nuovo->voto=info;
        nuovo->molteplicita=1;
        nuovo->next=NULL;
        return nuovo;
}


void StampaLista(struct elem *p)
{
        printf("--Inizio lista\n");
        while(p!=NULL) {
                printf("Voto: %hd\tMolteplicita`: %hd\n", p->voto, p->molteplicita);
                p=p->next;
        }
        printf("--Fine lista\n\n");
        return;
}