Università degli Studi di Udine Corsi di laurea in Ing. Gestionale FONDAMENTI DI INFORMATICA 11 marzo 2004 – Secondo compito di esonero Matricola ________________________ Nome ___________________________ Cognome ________________________ ISTRUZIONI (da leggere attentamente) 1) Svolgere l’elaborato sul foglio che verrà consegnato e firmato durante la prova dal personale di sorveglianza. Conservare il presente testo per la correzione del progamma in preparazione della prova orale. 2) Lo studente è tenuto a scrivere, correggere, compilare ed eseguire su computer (a casa o in laboratorio) gli esercizi di programmazione prima della prova orale. Alla prova orale lo studente deve portare un floppy disk contenente i sorgenti dei programmi corretti e le stampe dei relativi file. 3) Non è consentito l’uso di libri, appunti, calcolatrici programmabili, telefoni cellulari. 1. (25 punti, così ripartiti: 10 punti per il main, per la definizione dei tipi di dato necessari e per la scomposizione in sottoproblemi, 15 punti per l’implementazione delle funzioni) Si vuole simulare una variante informatizzata del gioco della tombola, facendo uso di due file: il primo contiene i numeri della cartella (cioè quelli che si spera vengano estratti), il secondo l’elenco dei numeri effettivamente estratti. Entrambi i file sono in formato ASCII e contengono soltanto numeri interi rappresentabili su 32 bit (molti di più, quindi, rispetto ai numeri della tombola). Si scriva in linguaggio C il programma tombola.c che riceva sulla riga di comando i nomi dei due file e scriva sul monitor dopo quante estrazioni (cioè a che punto della sequenza dei numeri estratti) la cartella è stata completata (cioè tutti i numeri in essa contenuti sono stati estratti), oppure segnali che la cartella non è stata completata al termine della sequenza di numeri estratti. NOTE: il numero di valori contenuti nella cartella è variabile (dipende dalla lunghezza del primo file), ma sicuramente non è superiore a 1000; il minimo e il massimo valore dei numeri che possono far parte della cartella e che possono essere estratti sono ignoti, seppur rappresentabili su 32 bit; il file contenente i valori della cartella non può avere valori duplicati, mentre uno stesso numero può essere estratto più volte, e quindi comparire più volte nel file dei numeri estratti; la sequenza di numeri estratti è di lunghezza ignota. Esempio 1: FILE CARTELLA1.TXT 10 234 33 1792 FILE SEQUENZA1.TXT 4 9990 77 334 33 10 6657 10 1792 0 234 45 12 3 C:\PROGRAMMI>tombola cartella1.txt sequenza1.txt cartella completata alla estrazione n. 11 Esempio 2: FILE CARTELLA2.TXT 4 90 11 FILE SEQUENZA2.TXT 23 1 55 7 98 4 66 11 55 4 C:\PROGRAMMI>tombola cartella2.txt sequenza2.txt la cartella non e` stata completata SUGGERIMENTO: le vere cartelle della tombola consistono in un insieme di coppie di informazioni: 1) il numero e 2) il fatto che tale numero sia già stato estratto o meno. Le stesse informazioni dovranno essere memorizzate dal programma. #include <stdio.h> #include <stdlib.h> #define MAXDIMCARTELLA 1000 #define VERO 1 #define FALSO 0 struct numero_in_cartella { int valore; unsigned char estratto; }; int gioca_a_tombola (FILE *fcartella, FILE *festratti); int carica_cartella (FILE *fcartella, struct numero_in_cartella cartella[]); int cerca_in_cartella (struct numero_in_cartella cartella[], int dim_cartella, int numero); int cartella_completa (struct numero_in_cartella cartella[], int dim_cartella); int main (int argc, char *argv[]) { FILE *fcartella, *festratti; int n; if (argc != 3) { printf ("Errato numero di argomenti\n"); exit (EXIT_FAILURE); } if ((fcartella = fopen (argv[1], "r")) == NULL) { printf ("errore di apertura del file %s\n", argv[1]); exit (EXIT_FAILURE); } if ((festratti = fopen (argv[2], "r")) == NULL) { printf ("errore di apertura del file %s\n", argv[1]); exit (EXIT_FAILURE); } n = gioca_a_tombola (fcartella, festratti); if (n != 0) printf ("cartella completata alla estrazione n. %d\n", n); else printf ("la cartella non e` stata completata\n"); return EXIT_SUCCESS; } int gioca_a_tombola (FILE *fcartella, FILE *festratti) { struct numero_in_cartella cartella[MAXDIMCARTELLA]; int dim_cartella; int n_estratto; int indice, conta_estrazione; dim_cartella = carica_cartella (fcartella, cartella); conta_estrazione = 0; while (fscanf (festratti, "%d", &n_estratto) != EOF) { conta_estrazione++; indice = cerca_in_cartella (cartella, dim_cartella, n_estratto); if (indice != -1) { cartella[indice].estratto = VERO; if (cartella_completa (cartella, dim_cartella)) return conta_estrazione; } } return 0; } int carica_cartella (FILE *fcartella, struct numero_in_cartella cartella[]) { int i, numero; i = 0; while (fscanf (fcartella, "%d", &numero) != EOF) { cartella[i].valore = numero; cartella[i].estratto = FALSO; i++; } return i; } int cerca_in_cartella (struct numero_in_cartella cartella[], int dim_cartella, int numero) { int i; i = 0; while (i < dim_cartella) { if (cartella[i].valore == numero) return i; i++; } return -1; } int cartella_completa (struct numero_in_cartella cartella[], int dim_cartella) { int i; i = 0; while (i < dim_cartella) { if (cartella[i].estratto == FALSO) return 0; i++; } return 1; } 2. (7 punti) Si scriva la funzione void specchio (char s[], char t[]) che copia nella stringa s la stringa t e la sua “immagine” riflessa. Esempi: t = "CIAO" → s = "CIAOOAIC" t = "testo di prova" → s = "testo di provaavorp id otset" void specchio (char s[], char t[]) { int i, j; i = j = 0; while (t[i] != '\0') s[j++] = t[i++]; i--; while (i >= 0) s[j++] = t[i--]; s[j] = '\0'; return; }