• Non ci sono risultati.

Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I Prova scritta del 15 febbraio 2016

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 15 febbraio 2016"

Copied!
4
0
0

Testo completo

(1)

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

Prova scritta del 15 febbraio 2016

Esercizio 2 (15 punti)

Un file di testo contiene la descrizione dei salti di un punto in un piano rappresentato da una matrice di interi di dimensioni 20x20. La posizione iniziale del punto sia { 0, 0 } e la descrizione dei salti sia nel formato deducibile dal seguente esempio:

x +3; y +15; x +8; y -5; x -3; y +7; x -2;

y -12; x +9;

Una riga del file può contenere uno o più salti, il primo termine identifica la coordinata e il secondo la lunghezza e la direzione del salto. Per esempio, se la posizione corrente del punto è { 10, 10 } il salto y +5; porta il punto nella posizione { 10, 15 }, e il successivo salto x -2; porta il punto nella posizione { 8, 15 }.

Si scriva un programma che riceva sulla linea di comando il nome di un file di salti nel formato di cui sopra, tracci nella matrice i salti in esso descritti e disegni sul video il percorso effettuato dal punto. In ogni posizione della matrice in cui il punto approda va scritto il numero progressivo del salto (attribuendo 1 alla posizione di partenza). Qualora il punto passi più volte nella stessa posizione, la cella dovrà riportare solo il numero dell’ultimo salto.

Nel caso dell’esempio sopra riportato, il programma deve stampare il disegno qui di fianco (gli assi x e y di riferimento sono quelli delle normali coordinate cartesiane).

#include <stdio.h>

#include <stdlib.h>

#define N 20 struct salto {

char coordinata;

int spostamento;

};

void traccia_salti (FILE *fp);

void carica_salti (FILE *fp, int piano[N][N], int x_iniziale, int y_iniziale);

void esegui_salto (int piano[N][N], struct salto m, int *px, int *py, int contatore);

void visualizza_piano (int piano[N][N]);

int estrai_numero (char s[]);

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

FILE *fp;

if (argc != 2) {

printf ("ERRORE: salti_punto_nel_piano <nomefile>\n");

exit (EXIT_FAILURE);

}

if ((fp = fopen (argv[1], "r")) == NULL) {

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

exit (EXIT_FAILURE);

}

traccia_salti (fp);

. . . . . . . . . . . 8 . 7 . . . . . . . . . . . 3 . . . 4 . . . . . . . . . . . . . . . . . . . . . . . 6 . . 5 . . . . . . . . . . . . . . . . . . . . . . . 9 . . . . 10 . . . . . . . . . . . . . . . . . . . . 1 . . 2 . . . .

(2)

fclose (fp);

return EXIT_SUCCESS;

}

void traccia_salti (FILE *fp) {

int piano[N][N] = { 0 };

carica_salti (fp, piano, 0, 0);

visualizza_piano (piano);

return;

}

void carica_salti (FILE *fp, int piano[N][N], int x_corrente, int y_corrente) {

char str_1[8], str_2[8];

struct salto m;

int cnt;

piano [x_corrente][y_corrente] = 1;

cnt = 1;

while (fscanf (fp, "%s %s", str_1, str_2) != EOF) {

m.coordinata = str_1[0];

m.spostamento = estrai_numero (str_2);

cnt++;

esegui_salto (piano, m, &x_corrente, &y_corrente, cnt);

} return;

}

int estrai_numero (char s[]) {

s[strlen(s)-1] = '\0'; /* rimuove il punto e virgola */

return atoi(s);

}

void esegui_salto (int piano[N][N], struct salto m, int *px, int *py, int contatore) {

int i;

if (m.coordinata == 'x') *px += m.spostamento;

else

*py += m.spostamento;

piano[*py][*px] = contatore;

return;

}

void visualizza_piano (int piano[N][N]) {

int x, y;

for (y = N-1; y >= 0; y--) {

for (x = 0; x < N; x++) {

if (piano[y][x] == 0) printf (" . ");

else

printf ("%2d ", piano[y][x]);

}

printf ("\n");

} return;

}

Esercizio 2 (15 punti)

Un file di testo contiene le date di nascita e il soprannome di un numero imprecisato di persone. Ogni riga contiene i dati di una persona, nel formato che può essere dedotto dall’esempio a lato. Si osservi che i nomi dei mesi sono sempre indicati dalle prime tre lettere minuscole del nome in italiano e che i soprannomi sono sempre composti da una sola parola.

3-feb-1970: DarthVader 23-ago-1968: Spider 18-set-2000: Quercia

1-nov-1998: ColpoDellaStrega

(3)

Si assuma già disponible la funzione int confronta_date (struct data d1, struct data d2); che, ricevendo le due date nella consueta struttura struct data composta da tre campi interi, restituisce 0 se le due date sono uguali, un valore minore di zero se la data d1 è precedente a d2 e un valore maggiore di zero altrimenti.

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 chiamante) e che restituisca, in un’apposita struttura, soprannome e data di nascita della persona più giovane presente nel file. Per semplicità si può assumere che il file contenga sempre almeno una riga di dati. Nel caso in cui siano più persone di età minima nate esattamente lo stesso giorno dovrà essere restituita la prima di esse presente nel file.

#include <stdio.h>

#include <stdlib.h>

struct data {

int giorno;

int mese;

int anno;

};

int confronta_date (struct data d1, struct data d2) /* non richiesta nella prova di esame */

{

/* restituisce -1 se d1 < d2, 0 se d1 == d2, +1 se d1 > d2 */

if (d1.anno < d2.anno) return -1;

else if (d1.anno > d2.anno) return +1;

else {

/* stesso anno */

if (d1.mese < d2.mese) return -1;

else if (d1.mese > d2.mese) return +1;

else {

/* stesso anno e stesso mese */

if (d1.giorno < d2.giorno) return -1;

else if (d1.giorno > d2.giorno) return +1;

else

return 0;

} } }

struct persona {

char soprannome[64];

struct data data_di_nascita;

};

struct persona il_piu_giovane (FILE *fp);

struct data estrai_data (char s_data[]);

int numero_mese (char nome_mese[]);

int main (int argc, char *argv[]) /* non richiesto nella prova di esame */

{

FILE *fp;

struct persona p;

if (argc != 2) {

printf ("USO: il_piu_giovane <nomefile>\n");

exit (EXIT_FAILURE);

}

if ((fp = fopen (argv[1], "r")) == NULL) {

printf ("errore apertura file %s\n", argv[1]);

exit (EXIT_FAILURE);

}

p = il_piu_giovane (fp);

printf ("%s, %d/%d/%d\n", p.soprannome,

p.data_di_nascita.giorno, p.data_di_nascita.mese, p.data_di_nascita.anno);

(4)

fclose (fp);

return EXIT_SUCCESS;

}

struct persona il_piu_giovane (FILE *fp) {

char s_data[128];

struct persona p_corrente, p_piu_giovane, p_vuota = { "", { -1, -1, -1 } };

int minimo_inizializzato = 0; /* facoltativo: consente di gestire anche file vuoti */

while (fscanf (fp, "%s %s", s_data, p_corrente.soprannome) != EOF) {

p_corrente.data_di_nascita = estrai_data (s_data);

if (!minimo_inizializzato) {

p_piu_giovane = p_corrente;

minimo_inizializzato = 1;

} else {

if (confronta_date (p_corrente.data_di_nascita, p_piu_giovane.data_di_nascita) > 0) {

p_piu_giovane = p_corrente;

} } }

if (minimo_inizializzato) return p_piu_giovane;

else

return p_vuota;

}

struct data estrai_data (char s_data[]) {

struct data d;

char t[64];

int i, j;

i = 0;

j = 0;

while (s_data[i] != '-') t[j++] = s_data[i++];

t[j] = '\0';

d.giorno = atoi(t);

i++;

j = 0;

while (s_data[i] != '-') t[j++] = s_data[i++];

t[j] = '\0';

d.mese = numero_mese(t);

i++;

j = 0;

while (s_data[i] != ':') t[j++] = s_data[i++];

t[j] = '\0';

d.anno = atoi(t);

i++;

return d;

}

int numero_mese (char nome_mese[]) {

char nomi_mesi[13][4] =

{ "", "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic" };

int i;

i = 0;

while (i < 13) {

if (strcmp (nomi_mesi[i], nome_mese) == 0) return i;

i++;

}

return -1;

}

Riferimenti

Documenti correlati

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 che riceva come argomenti il nome del file di equivalenze sopra descritto, il nome di un file di grandezze (con i punti interrogativi) e il nome di un file

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