Formula 1, Campionato
Si adatti il programma che risolve il problema della singola gara al fine di leggere da un file l'ordine d'arrivo di un intero campionato di Formula 1 composto da più gare. Le prime 20 righe sono relative alla prima gara. Seguono 20 righe relative alla seconda gara, e così via.
Il programma dovrà essere in grado di svolgere le seguenti elaborazioni.
Suggerimenti generali
Ricorda che le righe nel file rispecchiano l'ordine di arrivo nella gara! Puoi memorizzare il punteggio assegnato per ciascuna posizione di classifica in un vettore, in modo che l'indice del vettore, legato alla posizione in classifica, permetta di recuperare con una istruzione il punteggio del pilota; per esempio:
int punti_per_pos[POS_A_PUNTI] = {
25, 18, 15, 12, 10, 8, 6, 4, 2, 1
};
dove POS_A_PUNTI
è una costante definita con una #define
(vedi S3.1) che indica il numero di posizioni che permettono di ottenere dei punti.
Puoi utilizzare una struttura dati per memorizzare l'associazione tra pilota e punteggio, per esempio:
struct classificato {
char nome[MAX_RIGA + 1];
int punti;
};
dove MAX_RIGA
è una costante definita con una #define
(vedi S3.1) che indica la dimensione massima della riga di testo.
Sarà necessario un vettore di tali strutture per memorizzare i punteggi dei piloti (nel main
):
struct classificato piloti[N_PILOTI];
dove N_PILOTI
è una costante definita con una #define
(vedi S3.1) che indica il numero di piloti che gareggiano.
Il nome del file da leggere sarà l'argomento argv[1]
del main
(vedi S6.9), mentre per aprire il file in lettura si usa fopen
(S8.2.1).
Funzione di lettura
Creare una funzione di lettura dichiarata come la segue:
int leggi_gara(FILE * fin,
struct classificato *piloti,
struct classificato *scuderie);
La funzione richiede tre 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 vettore
scuderie
di strutture di tipostruct classificato
per memorizzare i punteggi delle squadre, passato per riferimento (S6.6)
La funzione leggi_gara
restituirà il numero di piloti caricati per la gara corrente.
Quando restituisce 0, significa che è stata raggiunta la fine del file.
Nella funzione leggi_gara
:
- leggere il file con un ciclo attraverso
fgets
(S8.6) - da ogni riga, estrarre il nome del pilota tramite
sscanf
, determinare il punteggio e memorizzare questi valori in un elemento del vettorepiloti
- si ricorda che per estrarre una stringa con
sscanf
si usa lo specificatore%s
- nella
sscanf
, la variabile stringa nella quale memorizzare il nome estratto va passato per riferimento (se si tratta di un vettore dichar
non serve la&
) - il nome va copiato tramite
strcpy
nel campo della struttura giusta del vettorepiloti
- si ricorda che per estrarre una stringa con
Nel main
:
- chiamare la funzione
leggi_gara
in un ciclo come segue (piloti
escuderie
sono vettori opportunamente dichiarati nelmain
):
while (leggi_gara(fin, piloti, scuderie) != 0) {
/* quando leggi_gara ritorna, una gara intera e` stata letta */
.....
}
- elaborare opportunamente il contenuto dei vettori
piloti
escuderie
Per poter funzionare, la leggi_gara
deve poter cercare un elemento dentro un vettore di strutture struct classificato
il cui campo nome
corrisponde ad un nome specificato.
La funzione di ricerca può essere dichiarata come segue:
struct classificato *cerca_classificato(struct classificato
*elenco, int size,
char *nome);
I parametri sono i seguenti:
elenco
è il vettore di strutture sul quale fare la ricercasize
è il numero di strutture presenti nel vettorenome
è la stringa che specifica il nome da ricercare
La funzione restituisce l'indirizzo dell'elemento all'interno di elenco
che abbia il campo nome
uguale alla stringa nome
passata come argomento.
La funzione deve considerare due casi:
- un elemento con il nome desiderato è già presente in
elenco
, nel qual caso si ritorna l'indirizzo di quell'elemento - un elemento con il nome desiderato non è già presente in
elenco
(questo si verifica durante la lettura della prima gara nel file); quindi la funzionecerca_classificato
dovrà:
- restituire l'indirizzo del primo elemento del vettore che non contiene alcun nome
- inizializzare tale elemento inserendo il nome (con
strcpy
) e inizializzando a 0 il valore dei punti
La funzione cerca_classificato
potrà essere chiamata all'interno di leggi_gara
sia per cercare il nome di un pilota all'interno del vettore piloti
che per cercare il nome di una squadra all'interno del vettore scuderie
.
Per capire meglio come operano le funzioni leggi_gara
e cerca_classificato
si veda l'esempio di soluzione qui.
1) Numero di gare
Determinare il numero di gare presenti nel file, stampandone il valore usando il formato:
[NUMERO_GARE]
2
Suggerimenti
La funzione leggi_gara
dovrà leggere al massimo un numero di righe pari al numero di piloti che gareggiano in ciascuna gara, in questo modo la funzione può essere chiamata più volte in un ciclo while
nel main
per sommare i punteggi delle varie gare.
Si può contare il numero di volte che la funzione leggi_gara
viene chiamata per sapere il numero di gare memorizzate nel file.
2) Pilota vincitore
Determinare il pilota vincitore del campionato Il punteggio di un pilota è la somma dei punti ottenuti nelle singole gare. A parità di punteggio vince il pilota che viene prima in ordine alfabetico.
Stampare il nome del pilota usando il seguente formato:
[PILOTA_VINCITORE]
pilota punteggio
3) Squadra vincitrice
Determinare la squadra vincitrice del campionato. Considerando che il punteggio di una squadra consiste nella somma dei punti ottenuti dai suoi piloti, determinare la squadra vincitrice.
Stampare il nome della squadra usando il seguente formato:
[SQUADRA_VINCITRICE]
squadra punteggio
A parità di punteggio vince la squadra che viene prima in ordine alfabetico.
Verifica automatica
Si utilizzi il tool pvcheck
di verifica automatica per testare il corretto funzionamento del programma.
Il file contenente i test è formula1_2.test.
Per poter eseguire i test con pvcheck
è necessario scaricare anche i seguenti file di dati, da salvare nella medesima directory del file di test:
Il comando da eseguire per il test è il seguente:
pvcheck -f formula1_2.test ./a.out
Nella prossima pagina potrai esaminare un esempio di soluzione dell'esercizio.