#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_CHAR_STAZ 33 /* numero caratteri
* massimo per stazione
* piu'uno per fine stringa */
/* struttura contenente le stazioni,
* scelgo una lista singolarmente concatenata */
struct stazione{
unsigned int distanza;
unsigned int costo_per_km;
char nome[MAX_CHAR_STAZ];
struct stazione *prossimo;
};
/* prototipi */
void aggiungi_stazione(struct stazione*, struct stazione*);
struct stazione *cerca_stazione(struct stazione*, char *);
int calcola_costo(struct stazione*, struct stazione*);
void *Malloc(size_t);
FILE *Fopen(const char *, const char *);
int main(int argc, char **argv)
{
FILE *mystream;
struct stazione *tmp;
struct stazione *tratta;
int numdati;
char stazione1[MAX_CHAR_STAZ], stazione2[MAX_CHAR_STAZ];
struct stazione *p1, *p2;
int costo_totale;
/* PRIMA PARTE: LEGGO E MEMORIZZO I DATI */
/* apro il file */
mystream=Fopen("STAZIONI.TXT", "r");
printf("Sto leggendo i dati");
tratta=NULL;
while(!feof(mystream))
{
/* alloco un puntatore temporeaneo che serve per contenere i
* dati via via che sono letti */
tmp=Malloc(sizeof(struct stazione));
tmp->prossimo=NULL;
/* leggo la riga ed esco se non esiste */
numdati=fscanf(mystream,"%d#%d#%[^\n]\n", &tmp->distanza, &tmp->costo_per_km, tmp->nome);
/* se non vi sono errori nel file deve aver
* letto 3 elementi */
if(numdati!=3)break;
printf(".");
/* ora devo aggiungere la stazione alla lista
* prima controllo se esiste la lista */
if(!tratta){
/* non esiste, quindi la stazione letta
* diventa la testa della lista */
tratta=tmp;
}else{
aggiungi_stazione(tratta, tmp);
}
}/*while*/
printf("\n");
/* SECONDA PARTE: CHIEDO DUE STAZIONI E CALCOLO LA DISTANZA */
while(1){
printf("Inserire nome prima stazione: ");
fgets(stazione1, MAX_CHAR_STAZ, stdin);
/* fgets inserisce un ``a capo'', lo
* limino */
stazione1[strlen(stazione1)-1]='\0';
p1=cerca_stazione(tratta, stazione1);
if(!p1){
fprintf(stderr, "Errore stazione non trovata!\n");
continue;
}
printf("Inserire nome seconda stazione: ");
fgets(stazione2, MAX_CHAR_STAZ, stdin);
stazione2[strlen(stazione2)-1]='\0';
p2=cerca_stazione(tratta, stazione2);
if(!p2){
fprintf(stderr, "Errore stazione non trovata!\n");
continue;
}
if(p2==p1){
fprintf(stderr, "Errore: inserire due stazioni differenti!\n");
continue;
}
/* il calcolo della distanza e'semplice */
printf("Distanza: %d\n", abs(p1->distanza-p2->distanza));
/* per calcolare il costo totale occorre scorrere
* la lista */
/* il file e' ordinato in funzione della
* distanza, cerco di capire in che ordine scorrere
* la lista */
if(p1->distanza>p2->distanza)
costo_totale=calcola_costo(p2, p1);
else
costo_totale=calcola_costo(p1, p2);
printf("Costo: %d\n", costo_totale);
}/*while*/
}
/* cerca una stazione nella lista, ritorna l'indirizzo in memoria se la trova
* oppure NULL in caso non la trovi */
struct stazione *cerca_stazione(struct stazione *lista, char *nome){
/* scorro la lista fino a che non trovo il
* nome di stazione che sto cercando o
* fino a quando non sono a fine lista */
for(;lista!=NULL;lista=lista->prossimo)
if(!strcmp(nome, lista->nome))
break;
/* ritorno il valore trovato
* oppure NULL */
return lista;
}
/* aggiunge una stazione alla lista di stazioni semplicemente accodandola */
void aggiungi_stazione(struct stazione *lista, struct stazione *nuovo){
/* scorro la lista fino al penultimo elemento */
for(;lista->prossimo;lista=lista->prossimo);
/* ora p punta all'ultimo elemento, a seguire aggiungo
* la nuova stazione */
lista->prossimo=nuovo;
}
/* questa procedura calcola il costo complessivo della
* tratta. Attenzione: a deve essere prima di b nel file */
int calcola_costo(struct stazione *a, struct stazione *b){
int costo=0;
/* percorro la lista per calcolare il costo */
for(;a!=b;a=a->prossimo)
costo+=(a->prossimo->distanza-a->distanza)*a->costo_per_km;
return costo;
}
/*************************************************************************/
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)
{
printf("Non riesco ad aprire il file %s in maniera %s\n",nome, modo);
perror("Fopen");
exit(1);
}
return tmp;
}