• Non ci sono risultati.

Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I Prova scritta del 1o luglio 2014

N/A
N/A
Protected

Academic year: 2021

Condividi "Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I Prova scritta del 1o luglio 2014"

Copied!
5
0
0

Testo completo

(1)

Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I

Prova scritta del 1

o

luglio 2014 Esercizio 1 (17 punti)

Un file di testo è utilizzato per rappresentare un insieme di sequenze di numeri interi.

Ogni numero è scritto su una riga del file e può essere immediatamente seguito dal carattere ';' (e in tal caso il numero appartiene a tutte le sequenze) oppure dal carattere '|', da un secondo numero e infine dal ';'. In questo caso il secondo numero rappresenta un’alternativa al primo e quidi appartiene a una sequenza diversa.

Le sequenze rappresentate dal file sono tutte quelle che contengono un numero preso da ciascuna riga in tutte le possibili combinazioni.

Si veda l’esempio a lato.

Si scriva una funzione in linguaggio C che riceva come argomenti il nome di un file siffatto e una matrice quadrata di interi. La dimensione della matrice sia definita da una costante N. La funzione deve riempire le righe della matrice secondo lo schema sopra riportato e restituire, in un’apposita struttura, il numero di righe riempite e la loro lunghezza (cioè la lunghezza delle sequenze generate, che è la stessa per tutte).

Si assuma che la matrice sia sufficientemente grande per contenere tutte le sequenze generate tramite il file di ingresso. Si assuma inoltre che il file contenga almeno un numero e quindi esista almeno una sequenza.

Si osservi che ogni volta che si incontra una coppia di valori alternativi è necessario risolvere questi due sottoproblemi:

- raddoppiare le righe della matrice riempite finora;

- aggiungere alle righe originali il primo valore della coppia e a quelle ricopiate il secondo valore.

#include <stdio.h>

#include <stdlib.h>

#define N 100

struct dimensioni {

int numero_sequenze;

int lunghezza_sequenze;

};

struct dimensioni genera_sequenze (char nomefile[], int m[N][N]);

void raddoppia_righe (int m[N][N], int r, int c);

void aggiungi_valore (int v, int m[N][N], int prima_riga, int ultima_riga, int ncolonne);

void stampa_matrice (int m[N][N], int r, int c);

int main (int argc, char *argv[]) {

int m[N][N];

struct dimensioni dim;

if (argc != 2) {

printf ("serve il nome del file\n");

exit (EXIT_FAILURE);

}

dim = genera_sequenze (argv[1], m);

stampa_matrice (m, dim.numero_sequenze, dim.lunghezza_sequenze);

return EXIT_SUCCESS;

}

Per esempio, il file

12;

34|37;

1|255;

4;

5|9;

rappresenta le sequenze:

12 34 1 4 5

12 37 1 4 5

12 34 255 4 5

12 37 255 4 5

12 34 1 4 9

12 37 1 4 9

12 34 255 4 9

12 37 255 4 9

(2)

struct dimensioni genera_sequenze (char nomefile[], int m[N][N]) {

FILE *fpin;

int nsequenze, lsequenze;

int valore, valore_alt;

char separatore;

struct dimensioni dim;

nsequenze = 1; /* esiste almeno una sequenza, al limite di lunghezza nulla */

lsequenze = 0;

if ((fpin = fopen (nomefile, "r")) == NULL) {

printf ("errore apertura file di ingresso\n");

exit (EXIT_FAILURE);

}

while (fscanf (fpin, "%d%c", &valore, &separatore) != EOF) {

if (separatore == ';') {

aggiungi_valore (valore, m, 0, nsequenze-1, lsequenze);

lsequenze++;

}

else /* separatore era '|' */

{

fscanf (fpin, "%d%c", &valore_alt, &separatore);

raddoppia_righe (m, nsequenze, lsequenze);

aggiungi_valore (valore, m, 0, nsequenze-1, lsequenze);

aggiungi_valore (valore_alt, m, nsequenze, 2*nsequenze, lsequenze);

lsequenze++;

nsequenze = nsequenze * 2;

} }

fclose (fpin);

dim.numero_sequenze = nsequenze;

dim.lunghezza_sequenze = lsequenze;

return dim;

}

void raddoppia_righe (int m[N][N], int r, int c) {

int i, j;

for (i = 0; i < r; i++) for (j = 0; j < c; j++) m[r+i][j] = m[i][j];

return;

}

void aggiungi_valore (int v, int m[N][N], int prima_riga, int ultima_riga, int ncolonne) {

int i, j;

for (i = prima_riga; i <= ultima_riga; i++) m[i][ncolonne] = v;

return;

}

void stampa_matrice (int m[N][N], int r, int c) {

int i, j;

for (i = 0; i < r; i++) {

for (j = 0; j < c; j++) printf ("%5d", m[i][j]);

printf ("\n");

} return;

}

(3)

Esercizio 2 (13 punti)

Un file contiene le informazioni su un insieme di calciatori (uno per riga). Ciascuna riga contiene il nome completo (inteso come cognome e nome), il ruolo, il numero di gol segnati e il numero di presenze. Le informazioni sono separate tra loro da una virgola e uno spazio. Il nome può ovviamente contenere spazi, mentre il ruolo non ha spazi.

Come esempio, si consideri il seguente file.

Bianchi Mauro, attaccante, 10, 20 Rossi Paolo, difensore, 3, 25

Verdi Giuseppe, centrocampista, 7, 20 De Rossi Giovanni, centrocampista, 5, 18 Neri Pier Paolo, difensore, 6, 14

Bianchi Alessandro, attaccante, 9, 19 Viola Pier Giorgio, difensore, 6, 10

Si scriva una funzione C che riceva come parametri il nome di un file siffatto ed una stringa contenente un ruolo. La funzione deve restituire, tramite un ulteriore parametro, il nome completo del giocatore di quel ruolo che ha segnato più gol di tutti. A parità di gol segnati, si deve restituire l'ultimo in ordine di presenza nel file.

Nel file dell'esempio, se il ruolo è "centrocampista" la funzione deve restituire "Verdi Giuseppe", mentre se il ruolo è "difensore" deve restituire "Viola Pier Giorgio".

Nel caso in cui non siano presenti giocatori con il ruolo richiesto, la funzione dovrà restituire la stringa convenzionale "Nessun giocatore".

#include <stdio.h>

#include <stdlib.h>

struct calciatore {

char nome[64];

char ruolo[32];

int gol;

int presenze;

};

struct calciatore estrai_dati (char s[]);

void goleador (char nomefile[], char ruolo[], char nome_goleador[]);

int main (int argc, char *argv[]) {

char nome_goleador[64];

if (argc != 3) {

printf ("uso: calciatori <nomefile> <ruolo>\n");

exit (EXIT_FAILURE);

}

goleador (argv[1], argv[2], nome_goleador);

printf ("%s\n", nome_goleador);

return EXIT_SUCCESS;

}

(4)

struct calciatore estrai_dati (char s[]) {

struct calciatore c;

int i, j;

char t[32];

i = 0;

j = 0;

while (s[i] != '\0' && s[i] != ',') c.nome[j++] = s[i++];

c.nome[j] = '\0';

i++;

while (s[i] != '\0' && s[i] != ' ') i++;

i++;

j = 0;

while (s[i] != '\0' && s[i] != ',') c.ruolo[j++] = s[i++];

c.ruolo[j] = '\0';

while (s[i] != '\0' && s[i] != ' ') i++;

i++;

j = 0;

while (s[i] != '\0' && s[i] != ',') t[j++] = s[i++];

t[j] = '\0';

c.gol = atoi(t);

while (s[i] != '\0' && s[i] != ' ') i++;

i++;

j = 0;

while (s[i] != '\0' && s[i] != ',') t[j++] = s[i++];

t[j] = '\0';

c.presenze = atoi(t);

return c;

}

void goleador (char nomefile[], char ruolo[], char nome_goleador[]) {

FILE *fp;

char s[128];

struct calciatore c, cmigliore;

int inizializzato = 0;

if ((fp = fopen (nomefile, "r")) == NULL) {

printf ("errore di apertura del file di input\n");

exit (EXIT_FAILURE);

}

while (fgets (s, 128, fp) != NULL) {

c = estrai_dati (s);

if (!strcmp(c.ruolo, ruolo)) {

if (!inizializzato) {

cmigliore = c;

inizializzato = 1;

} else {

if (c.gol >= cmigliore.gol) cmigliore = c;

} } }

(5)

if (!inizializzato)

strcpy (nome_goleador, "Nessun giocatore");

else

strcpy (nome_goleador, cmigliore.nome);

return;

}

Riferimenti

Documenti correlati

Si scriva un programma in linguaggio C che riceva sulla riga di comando il nome di un file nel formato sopra descritto e stampi sul monitor il nome e l’elenco dei concorrenti

Si scriva una funzione in linguaggio C che riceva come argomenti un vettore di stringhe, contenenti ciascuna il nome di un file del tipo sopra descritto, e un

Si scriva una funzione in linguaggio C che riceva come argomenti il puntatore a un file di testo nel formato sopra descritto (il file è quindi già stato aperto dalla funzione

Si scriva un programma in linguaggio C che riceva sulla riga di comando il nome di un file di dizionario nel formato dell’esempio sopra riportato e il nome di un file

Al termine dell’esecuzione delle operazioni specificate nel file di ingresso il programma dovrà stampare i valori contenuti in tutte e sole le celle di memoria che

Si scriva un programma in linguaggio C che riceva sulla riga di comando il nome di due file come quelli sopra descritti e stampi il numero delle repliche

Poiché gli identificatori (numeri) delle tessere sono univoci e nella griglia è presente una sola posizione vuota, ogni mossa può semplicemente essere indicata

Per fare questo, si scriva un programma in linguaggio C che riceva sulla riga di comando il nome di un file come sopra descritto e stampi l’elenco dei