Formula 1, Gara singola - Soluzione
Soluzione
In questo tutorial non verrà presentata la possibile soluzione nella sua interezza, ma soltano le parti interessanti, che dovranno essere opportunamente integrate per fornire la soluzione completa e compilabile.
Per ottenere un programma completo e funzionante, si tratta pertanto di scrivere la funzione main
che dichiara le variabili necessarie e che chiama opportunamente le funzioni descritte.
Per cominciare, si assume che vengano effettuat le seguenti dichiarazioni:
#define N_SQUADRE (10)
#define N_PILOTI (20)
#define MAX_RIGA (50)
#define POS_A_PUNTI (10) /* Posizioni a cui si assegnano punti */
int punti_per_pos[POS_A_PUNTI] = {
25, 18, 15, 12, 10, 8, 6, 4, 2, 1
};
I dati saranno memorizzati in array di strutture. Piloti e squadre richiedono lo stesso tipo di informazioni (nome e punteggio). Pertanto conviene utilizzare lo stesso tipo, in questo modo si eviterà di replicare le funzioni che effettuano le elaborazioni:
struct classificato {
char nome[MAX_RIGA + 1];
int punti;
};
Le funzioni descritte di seguito dovranno essere oppotunamente richiamate nel main
.
Ad esse dovranno essere passati gli argomenti corretti.
1) Lettura e calcolo del punteggio
La funzione per la lettura può essere realizzata come segue:
void leggi_gara(FILE *fin, struct classificato *piloti)
{
char buffer[MAX_RIGA + 1];
int pos, punti;
char nome_pilota[MAX_RIGA + 1];
char nome_scuderia[MAX_RIGA + 1];
pos = 0;
while (pos < N_PILOTI && fgets(buffer, MAX_RIGA + 1, fin) != NULL) {
sscanf(buffer, "%s %s", nome_pilota, nome_scuderia);
if (pos < POS_A_PUNTI) {
punti = punti_per_pos[pos];
} else {
punti = 0;
}
strcpy(piloti[pos].nome, nome_pilota); /* Memorizza il nome */
piloti[pos].punti += punti; /* Assegna i punti */
pos++; /* Passaggio alla posizione successiva */
}
}
La funzione richiede due argomenti:
- il file da leggere, già aperto in lettura prima di chiamare
leggi_gara
(S8.2.1); - il vettore
piloti
di strutture di tipostruct classificato
per memorizzare i punteggi dei piloti, passato per riferimento (S6.6).
Il ciclo while
viene eseguito finché si registra il risultato di tutti i piloti attesi (pos < N_PILOTI
) e, contemporaneamente, finché ci sono righe nel file.
Ricorda che fgets
restituisce NULL
(quindi 0
, quindi "falso") quando si è giunti alla fine del file e non ci sono più righe da leggere (S8.6).
Per scrivere il nome del pilota nel campo della struttura va usata la strcpy
, perché l'assegnamento (operatore =
) non funziona con le stringhe (S5.11).
ATTENZIONE: l'istruzione che memorizza i punti del pilota è un incremento, quindi questa funzione si aspetta che il valore dei punti sia correttamente inizializzato a zero!
Inizializzazione del vettore di strutture
Visto che la funzione per il calcolo dei punti si attende un vettore correttamente inizializzato, è possibile incapsulare le istruzioni per l'inizializzazione in una funzione come la seguente:
void inizializza_elenco(struct classificato *elenco, int size)
{
int i;
for (i = 0; i < size; i++) {
elenco[i].nome[0] = '\0';
elenco[i].punti = 0;
}
}
Il campo stringa nome
viene posto uguale alla stringa vuota, mettendo il terminatore come primo carattere del vettore.
Il campo punti
viene inizializzato a zero.