/****************************************************** possibile soluzione
* alla verifica del 14 aprile 2000 mediante l'utilizzo di una
* rappresentazione concatenata e allocazione dinamica della memoria, il
* file in ingresso ha una sintassi rigida e quindi la lettura e' agevole,
* in generale NON e' cosi' per negli esami */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define D_LEN 51 /* massima lunghezza da testo
* e carattere fine stringa */
/* si e' scelto di usare una rappresentazione concatenata
* con testa fasulla al fine di evitare l'utilizzo
* di variabili globali */
struct nodo{
char descrizione[D_LEN];
long prezzo;
int num_pezzi;
struct nodo *prossimo;
};
/* prototipi funzioni */
void *Malloc(size_t);
FILE *Fopen(const char *, const char *);
struct nodo *inizializza_lista(void);
struct nodo *leggi_dati(FILE*);
void inserisci_in_lista(struct nodo*, struct nodo*);
void stampa_lista_in_file(struct nodo*, FILE*);
void calcola_totale(struct nodo*, unsigned long int*);
void libera_lista(struct nodo *);
int main(int argc, char **argv){
struct nodo *mialista, *nodotmp;
FILE *archivio;
unsigned long int totale;
/* apro file in ingresso */
archivio=Fopen("totali.txt","r");
/* creo la lista, visto che devo ordinare opto
* per una lista con testa fasulla e insertion
* sort */
mialista=inizializza_lista();
/* leggo i dati e li metto in lista */
while((nodotmp=leggi_dati(archivio))!=NULL)
inserisci_in_lista(mialista, nodotmp);
fclose(archivio);
archivio=Fopen("ris.txt","w");
/* stampo la lista, mi devo ricordare che il primo nodo
* e' fasullo */
stampa_lista_in_file(mialista->prossimo, archivio);
/* ripercorro la lista e computo il totale */
totale=0;
calcola_totale(mialista->prossimo, &totale);
fprintf(archivio, "\nTOTALE: %ld\n", totale);
fclose(archivio);
/* libero memoria */
libera_lista(mialista);
return 0;
}
/* creo la lista con un nodo iniziale fasullo
* in cui non metto dati */
struct nodo *inizializza_lista(void){
struct nodo *testa;
testa=Malloc(sizeof(struct nodo));
testa->prossimo=NULL;
/* restituisco indirizzo*/
return testa;
}
struct nodo *leggi_dati(FILE* a){
struct nodo *tmp;
int ris;
tmp=Malloc(sizeof(struct nodo));
tmp->prossimo=NULL;
/* la sintassi del file e' rigida (negli esami non avviene mai)
* e' comodo l'utilizzo di scanf e parenti */
ris=fscanf(a, "%ld#%d#%[^\n]",&tmp->prezzo,&tmp->num_pezzi,tmp->descrizione);
/* se non sono stati letti tre elementi o c'e'
* un errore nel file o sono in fondo */
if(ris<3){
free(tmp);
tmp=NULL;
}
return tmp;
}
void inserisci_in_lista(struct nodo* lista, struct nodo* nuovo){
struct nodo *p;
p=lista; /* primo nodo */
/* cerco il punto di inserzione */
while((p->prossimo!=NULL)&&(p->prossimo->prezzo<nuovo->prezzo))
p=p->prossimo;
/* inserisco */
nuovo->prossimo=p->prossimo;
p->prossimo=nuovo;
}
void stampa_lista_in_file(struct nodo* p, FILE* a){
if(p==NULL)return;
stampa_lista_in_file(p->prossimo, a);
fprintf(a, "%s\n", p->descrizione);
}
void calcola_totale(struct nodo* p, unsigned long int* t){
if(p==NULL)return;
*t+=p->prezzo*p->num_pezzi;
calcola_totale(p->prossimo, t);
}
void libera_lista(struct nodo *p){
if(p==NULL)return;
libera_lista(p->prossimo);
free(p);
}
/* funzioni gia' viste a lezione */
void *Malloc(size_t size)
{
void *genericp;
if((genericp=malloc(size))==NULL)
{
perror("Malloc");
exit(1);
}
return genericp;
}
FILE *Fopen(const char *nome, const char *modo)
{
FILE *tmp;
if((tmp=fopen(nome, modo))==NULL)
{
fprintf(stderr, "Non riesco ad aprire il file %s in maniera %s\n",nome, modo);
perror("Fopen");
exit(1);
}
return tmp;
}