Formula 1, Gara singola

Al campionato del mondo di Formula 1 partecipano 10 squadre, formate da 2 piloti ciascuna. L'ordine di arrivo di una gara viene memorizzato in un file di testo col seguente formato:

PILOTA1 SQUADRA1
PILOTA2 SQUADRA2
...

dove i nomi di piloti e squadre sono stringhe senza spazi, e dove ciascuna riga contiene al più 50 caratteri.

La prima riga contiene il nome del vincitore, la seconda quello del secondo arrivato, e così via. Tutti i piloti sono presenti nell'elenco, anche quelli che non sono giunti al traguardo. In ciascuna gara sono assegnati dei punti validi per la classifica mondiale: dal primo al decimo arrivato si assegnano 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 punti; i concorrenti che arrivano oltre la decima posizione non ottengono nessun punto.

1) Classifica della gara

Scrivere un programma C che legga il contenuto del file il cui nome è specificato come parametro della riga di comando e stampi i dati letti nel formato:

[ORDINE_PILOTI]
pilota1 punteggio
pilota2 punteggio
...
pilota20 punteggio

Suggerimenti generali

  • si ricordi che le righe nel file rispecchiano l'ordine di arrivo nella gara!
  • 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.

Utilizza 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 (nel main) un vettore di tali strutture per memorizzare i punteggi dei piloti:

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 con fopen (S8.2.1).

Funzione di lettura

La parte principale dell'elaborazione viene fatta durante la lettura del file. Quando viene letta una riga, questa viene elaborata per memorizzare i punteggi di piloti e scuderie.

Si può creare una funzione di lettura dichiarata come la segue:

void leggi_gara(FILE * fin, struct classificato *piloti);

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 tipo struct classificato per memorizzare i punteggi dei piloti, passato per riferimento (S6.6)

Nella funzione leggi_gara:

  • il file può essere letto con un ciclo attraverso fgets (S8.6)
  • da ogni riga, si estrae il nome del pilota tramite sscanf, e si determina il punteggio e si memorizzano questi valori in un elemento del vettore piloti
    • ricorda che per estrarre una stringa con sscanf si usa lo specificatore %s (S8.6!
    • nella sscanf, la variabile stringa nella quale memorizzare il nome estratto va passato per riferimento (e visto che si tratta di un vettore di char non serve la &)
    • il nome va copiato tramite strcpy nel campo della struttura giusta del vettore piloti

Nel main:

  • bisogna chiamare la funzione leggi_gara
  • va stampato il contenuto del vettore con un ciclo for

Verifica automatica

Si può utilizzare il tool pvcheck di verifica automatica per testare il corretto funzionamento del programma. Il file contenente i test è formula1_1.test. È necessario scaricare anche il file di dati campionato1.txt, da salvare nella medesima directory del file di test.

Il comando da eseguire per il test è il seguente:

pvcheck -f formula1_1.test ./a.out

Nella prossima pagina potrai esaminare un esempio di soluzione dell'esercizio.