• Non ci sono risultati.

Corsi di laurea in Ingegnera Elettronica e Ingegneria Gestionale Fondamenti di Programmazione / Fondamenti di Informatica I Prova scritta del 2 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 2 febbraio 2016"

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 2 febbraio 2016

Esercizio 1 (16 punti)

Un file di testo contiene le equivalenze tra unità di misura, nel formato che si evince dall’esempio a lato.

Le unità di misura sono sempre formate da una sola parola, il secondo elemento di ogni riga è sempre la freccia rappresentata con i caratteri “-->” e il quarto elemento è sempre un asterisco, ad indicare l’operazione di moltiplicazione necessaria per la conversione. Il file contiene al massimo 100 regole di traduzione.

Un secondo file, di lunghezza ignota, contiene delle grandezze che devono essere convertite, nel formato deducibile dall’esempio del riquadro a lato.

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 di uscita. La funzione deve copiare le righe del file di ingresso in quello di uscita sostituendo ai punti interrogativi i valori corretti.

Si assuma che per tutte le coppie di unità di misura utilizzate in ogni riga del file delle grandezze sia presente una regola di conversione nel file delle equivalenze (eventualmente da utilizzare invertita, come nei casi “9782 cmq

= ? mq” e “7 mm = ? m” dell’esempio). Quindi è sempre sufficiente cercare ed applicare una e una sola regola di conversione.

Relativamente agli esempi sopra riportati, al termine dell’esecuzione della funzione il file di uscita dovrà contenere quanto riportato a lato.

NOTA: è accettabile che il formato numerico dei dati di ingresso cambi nel file di uscita. Per esempio, “9782 cmq

= ? mq” può anche diventare “9.782e3 cmq = 0.9782 mq” o “7 km = ? m” può diventare “7.0 km = 7000.0 m”, ecc.

#include <stdio.h>

#include <stdlib.h>

#define MAXDIM 100 struct equivalenza {

char nome_da[32];

char nome_a[32];

double fattore_di_conversione;

};

struct conversione {

char nome_da[32];

char valore_da_str[32]; /* opzionale, serve per mantenere il formato */

double valore_da;

char nome_a[32];

double valore_a;

};

void esegui_conversioni (char nomefile_equivalenze[],

char nomefile_in[], char nomefile_out[]);

int carica_equivalenze (FILE *fp, struct equivalenza equivalenze[], int maxdim);

double fattore_conversione (char da[], char a[],

struct equivalenza equivalenze[], int dim);

m --> cm * 100 m --> mm * 1000 km --> m * 1000 mq --> cmq * 10000

7 km = ? m 123.56 m = ? cm 9782 cmq = ? mq 7 mm = ? m

7 km = 7000 m

123.56 m = 12356 cm

9782 cmq = 0.9782 mq

7 mm = 0.007 m

(2)

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

{

if (argc != 4) {

printf ("numero di argomenti sbagliato: "

"<file equivalenze> <file ingresso> <file uscita>\n");

exit (EXIT_FAILURE);

}

esegui_conversioni (argv[1], argv[2], argv[3]);

return EXIT_SUCCESS;

}

void esegui_conversioni (char nomefile_equivalenze[],

char nomefile_in[], char nomefile_out[]) {

struct conversione c;

struct equivalenza equivalenze[MAXDIM];

double fattore_di_conversione;

int dim;

FILE *fpeq, *fpin, *fpout;

if ((fpeq = fopen (nomefile_equivalenze, "r")) == NULL) {

printf ("errore apertura tabella equivalenze\n");

exit (EXIT_FAILURE);

}

dim = carica_equivalenze (fpeq, equivalenze, MAXDIM);

fclose (fpeq);

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

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

exit (EXIT_FAILURE);

}

if ((fpout = fopen (nomefile_out, "w")) == NULL) {

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

exit (EXIT_FAILURE);

}

while (fscanf (fpin, "%s %s %*s %*s %s",

c.valore_da_str, c.nome_da, c.nome_a) != EOF) {

c.valore_da = atof (c.valore_da_str);

fattore_di_conversione = fattore_conversione

(c.nome_da, c.nome_a, equivalenze, dim);

if (fattore_di_conversione < 0) {

printf ("errore: conversione da %s a %s non presente in tabella\n", c.nome_da, c.nome_a);

} else {

fprintf (fpout, "%s %s = %g %s\n", c.valore_da_str, c.nome_da,

c.valore_da * fattore_di_conversione, c.nome_a);

} }

fclose (fpin);

fclose (fpout);

return;

}

(3)

int carica_equivalenze (FILE *fp, struct equivalenza equivalenze[], int maxdim) {

int cnt = 0;

while (cnt < maxdim && fscanf (fp, "%s %*s %s %*s %lf",

equivalenze[cnt].nome_da, equivalenze[cnt].nome_a, &equivalenze[cnt].fattore_di_conversione) != EOF) {

cnt++;

}

return cnt;

}

double fattore_conversione (char da[], char a[],

struct equivalenza equivalenze[], int dim) {

int i;

/* cerca conversione diretta */

i = 0;

while (i < dim) {

if (strcmp (da, equivalenze[i].nome_da) == 0 &&

strcmp (a, equivalenze[i].nome_a) == 0) return equivalenze[i].fattore_di_conversione;

i++;

}

/* cerca conversione diretta */

i = 0;

while (i < dim) {

if (strcmp (da, equivalenze[i].nome_a) == 0 &&

strcmp (a, equivalenze[i].nome_da) == 0)

return 1.0 / equivalenze[i].fattore_di_conversione;

i++;

}

return -1;

}

(4)

Esercizio 2 (14 punti)

Due file di testo contengono due elenchi di nomi di lunghezza ignota. Ogni riga di ciascun file contiene uno e un solo nome, che può essere composto da più parole separate da spazi. I nomi in entrambi i file sono ordinati in ordine alfabetico e il formato in cui sono scritti

(spaziature, ecc.) è identico.

Si scriva un programma che riceva sulla riga di comando i nomi dei due file e stampi sul monitor i nomi che compaiono in entrambi i file.

Per esempio, se il contenuto dei due file è quello riportato nei riquadri a lato, il programma deve stampare il risultato che segue:

# nomi_in_entrambi_i_file autori_1.dat autori_2.dat Alessandro Baricco

Andy Weir Dan Brown

Herbert George Wells Matilde Asensi

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int stampa_nomi_in_comune (FILE *fp1, FILE *fp2);

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

FILE *fp1, *fp2;

if (argc != 3) {

printf ("servono i nomi di due file come argomenti\n");

exit (EXIT_FAILURE);

}

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

printf ("errore apertura file 1\n");

exit (EXIT_FAILURE);

}

if ((fp2 = fopen (argv[2], "r")) == NULL) {

printf ("errore apertura file 1\n");

exit (EXIT_FAILURE);

}

stampa_nomi_in_comune (fp1, fp2);

fclose (fp1);

fclose (fp2);

return EXIT_SUCCESS;

}

File autori_1.dat:

Alessandro Baricco Andrea Camilleri Andy Weir

Dan Brown

Herbert George Wells J. K. Rowling

Matilde Asensi

File autori_2.dat:

Alessandro Baricco Andy Weir

Dan Brown

Frank Schatzing Herbert George Wells Matilde Asensi

Umberto Eco

(5)

int leggi_nome (FILE *fp, char s[]) {

if (fgets (s, 64, fp) == NULL) return 0;

s[strlen(s)-1] = '\0'; /* rimuovi il '\n' */

return 1;

}

int stampa_nomi_in_comune (FILE *fp1, FILE *fp2) {

char s1[64], s2[64];

int confronto, fine = 0;

if (leggi_nome (fp1, s1) == 0) return;

if (leggi_nome (fp2, s2) == 0) return;

fine = 0;

while (!fine) {

confronto = strcmp (s1, s2);

if (confronto == 0) /* se uguali stampa e avanza in entrambi i file */

{

puts (s1);

if (leggi_nome (fp1, s1) == 0) fine = 1;

if (leggi_nome (fp2, s2) == 0) fine = 1;

} else {

/* avanza nel file la cui parola corrente viene prima in ordine alfabetico */

if (confronto < 0) {

if (leggi_nome (fp1, s1) == 0) fine = 1;

} else {

if (leggi_nome (fp2, s2) == 0) fine = 1;

} } } return;

}

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