Esercizio sulle liste in C: semplice gestione di un autonoleggio

Qualche tempo fa un amico mi ha chiesto se potevo risolvere l’esercizio d’esame del corso di programmazione del primo anno di ingegneria per la sua morosa. Si trattava di un programmino in C. Oggi ho ritrovato la soluzione che avevo proposto e già che ci sono faccio che parlarne, magari qualcuno con un problema simile potrebbe arrivarci e trovarlo utile.
Il testo del programma era:


Si realizzi un programma strutturato in C che gestisca il parco macchine di un autonoleggio. Il parco macchine ?® descritto da unfile macchine.txt avente il seguente formato: -targa- -km percorsi- -costo al km- -data- dove:
1. Il campo -targa- è una stringa di 7 caratteri che identifica in modo univoco la targa.
2. Il campo -km percorsi- è un numero intero che indica quanti Km sono stati percorsi dalla persona che ha affittato la macchina in una certa data.
3. Il campo -costo al Km- è un numero floatting point che indica il costo al Km per affittare la macchina.
4. Il campo -data- ?® una stringa che indica la data in cui la macchina è rientrata in sede a seguito del termine del noleggio, nel formato AAAAMMGG.
Il numero di righe contenute nel file non è noto a priori.
Un esempio di file macchine.txt è il seguente:

CW000GB 1200 0.10 20060105
AT736AM 150 0.15 20060106
AN150FZ 382 0.40 20060110
CW000GB 151 0.10 20060108
AN150FZ 95 0.40 20060201

Il programma deve fornire all'utente un menù che offra le seguenti funzioni:
1. Ricerca e stampa della targa del veicolo che, tra quelli del parco macchine dell'autonoleggio, ha percorso il numero minimo di Km.
2. Ricerca e stampa della targa del veicolo che, tra quelli del parco macchine dell'autonoleggio, è risultato essere il più remunerativo.
3. Fine del programma.

Indicazione non specificata nel testo ma da seguire comunque è quella di utilizzare come struttura dati una lista. Ok.
Il file contenente il programma è questo: noleggio.c
Esempio di file macchine.txt

Qui per continuare a leggere e vedere direttamente il codice:

// By Dede 
typedef struct macchina
{
       char targa[7];
       int km_percorsi;
       float costo_km;
       char data[8];
       struct macchina *next;
} car;

// ROUTINE DI GESTIONE DEGLI ERRORI
void GestioneErrori(int ErrCode)
{
	switch(ErrCode)
	{
		case 1:
			printf("Bisogna passare il nome del file come argomento.\n");
		break;
		
		case 2:
			printf("Si ?® verificato un errore nell'apertura del file.\n");
		break;	
	}
	
	exit(ErrCode);
}

// Alloca lo spazio necessario per un nuovo nodo; usata nella creazione della lista
car *newnode()
{
	return(car *)malloc(sizeof(car));
}


// Funzione per la creazione della lista
car *crea_lista(char *store)
{
	car *lis, *p, *last;
	FILE *fp;
	
	if((fp = fopen(store,"r")) == NULL)
			GestioneErrori(2);
			
	// PRIMO NODO
	last = newnode();		
	if(fscanf(fp,"%s %d %f %s ",&last->targa,&last->km_percorsi,&last->costo_km,&last->data) != EOF)
	{
		lis = last;
		last->next= NULL;	
	}
	else
		lis = NULL; // CASO DI LISTA VUOTA
	
	// NODI SUCCESSIVI
	p = newnode();
	while (fscanf(fp,"%s %d %f %s ",&p->targa,&p->km_percorsi,&p->costo_km,&p->data) != EOF)
	{
			p->next =NULL;
			last->next=p;
			last=p;
			p = newnode();	
	}
	
	free(p);
fclose(fp);
return(lis);
}
	

// Funzione per la ricerca dell'auto con meno km percorsi
car *min_km(car *lis)
{
	car *temp;
	int min;
	min = lis->km_percorsi;  // imposto la prima come minimo
	temp = lis;
	lis = lis->next;		
	while (lis != NULL)   // scorro la lista dal secondo
	{
		if (lis->km_percorsi < min)  // se auto corrente ha meno km di min...
			temp = lis;   // ...la imposto come nuovo minimo
		lis = lis->next;
	}	
	return temp;
}


// Funzione per la ricerca dell'auto pi?? remunerativa
car *max_guadagno(car *lis)
{
	car *temp;
	float max, a;
	max = (lis->km_percorsi * lis->costo_km); // imposto la prima come max
	temp = lis; 
	lis = lis->next;	
	while (lis != NULL)   // scorro la lista dal secondo
	{
		a = lis->km_percorsi * lis->costo_km;
		if (a > max)   // se auto corrente rende pi?? di max...
			temp = lis;  // ...la imposto come nuovo max
		lis = lis->next;
	}	
	return temp;	
}


// stampa un elemento di tipo car
void stampa_elemento(car *elem, FILE *fp)
{
		fprintf(fp,"----------------------------\n");
		fprintf(fp,"Targa: %s\n", elem->targa);
		fprintf(fp,"Km: %d\n", elem->km_percorsi);
		fprintf(fp,"Costo al Km: %.2f\n", elem->costo_km);
		fprintf(fp,"Ultima riconsegna: %s\n", elem->data);
		fprintf(fp,"----------------------------\n");
}


// stampa l'intera lista di auto disponibili
// (non richiesta dal programma ma usata in fase di sviluppo)
void stampa_lista(car *lis, FILE *fp)
{

	while (lis != NULL)
	{
		stampa_elemento(lis,fp);
		lis = lis->next;
	}

} 


// Stampa il manu all'utente per la selezione dell'operazione
void stampa_menu()
{
printf("\n+--------------------------------------+\n");
printf("|     MENU DI SELEZIONE OPERAZIONI     |\n");
printf("+--------------------------------------+\n");
printf("|  1) Ricerca veicolo con meno km      |\n");
printf("|  2) Ricerca veicolo pi?? remunerativo |\n");
printf("|  3) Termina programma                |\n");
printf("+--------------------------------------+\n");
}


// MAIN
main(int argc, char *argv[])
{
car *lista;
int scelta;

	if (argc != 2)
		GestioneErrori(1);

// creo la lista con i dati delle auto		
lista = crea_lista(argv[1]);

/*ciclo do-while che presenta continuamente il menu all'utente
fino a quando non sceglie di terminare il programma */ 
do
{
	stampa_menu();
	printf("Seleziona operazione richiesta: ");
	scanf("%d",&scelta);  // operazione richiesta
	
	switch(scelta) 
	{
		case 1:
					printf("\nIl veicolo ricercato ?® il seguente:\n");
					stampa_elemento(min_km(lista),stdout);	
		break;
		
		case 2:
					printf("\nIl veicolo ricercato ?® il seguente:\n");
					stampa_elemento(max_guadagno(lista),stdout);	
		break;
		
		case 3:
					printf("\nPROGRAMMA TERMINATO. Bye Bye\n");
		break;
		
		default:
				printf("Il numero inserito non corrisponde a nessuna operazione valida.\n");
		break;	
	}
	
}while ( scelta != 3);


} // FINE MAIN

Ah, per la cronaca, l’esame lo ha poi passato. :)

This entry was posted in $1$s. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *