Fondamenti di Programmazione     a.a. 2011-2012
Prova scritta - 17 luglio 2012
Avvertenze: non usare variabili globali; definire tutte le funzione ausiliarie usate; è consentito usare le funzioni della libreria standard; se una soluzione non è scritta in modo chiaro ed ordinato non sarà presa in considerazione.
Esercizio 1 (max 12 punti)
Scrivere una funzione int *rows(int n, char *M[n][n], char *s, int *pR) che ritorna in un array, allocato dinamicamente, gli indici delle righe della matrice di stringhe M che contengono la stringa s; in *pR restituisce il numero di righe che deve anche essere uguale alla dimensione dell'array ritornato. Se la stringa s non compare nella matrice, ritorna NULL e restituisce 0 in *pR. Ad esempio, se la matrice è
"red"    "green"  "yellow"
"brown"  "blue"   "brown"
"blue"   "red"    "red"
(quindi n = 3) e s = "red", la funzione ritorna l'array [0, 2] e in *pR restituisce 2.
Esercizio 2 (max 12 punti)
Si consideri il seguente tipo:
typedef struct {
    long     code;
    char     descr[40];
} Rec;
Scrivere una funzione void update(char *fname, void (*upF)(Rec *)) che preso in input il nome fname di un file binario che contiene una sequenza di records di tipo Rec, legge ogni record del file e lo riscrive dopo averlo aggiornato tramite la funzione upF. Ad esempio, se il file contiene {1203,"vite"},{1204,"chiodo"},{1208,"martello"},{1207,"bullone"} e la funzione upF aggiorna i records con campo code pari scrivendo in maiuscole il contenuto del campo descr, allora la funzione aggiorna il file così {1203,"vite"},{1204,"CHIODO"},{1208,"MARTELLO"},{1207,"bullone"}.
Esercizio 3 (max 14 punti)
Si consideri il seguente tipo:
typedef struct Elem {
    int          code;
    char *       str;    //stringa allocata dinamicamente
    struct Elem *next;
} Elem, *List;
Scrivere una funzione void compact(List L) che riduce ogni sottolista di L formata da elementi consecutivi con lo stesso codice (campo code) a un solo elemento che contiene nel campo str la concatenazione di tutte le stringhe degli elementi della sottolista. Il puntatore al primo elemento della lista non deve essere modificato e la memoria degli elementi eliminati deve essere rilasciata. Ad esempio, se la lista è
{100, "La"} → {100, "Li"} → {100, "La"} → {110, "Lu"} → 
    → {105, "Lo"} → {105, "La"} → {100, "Li"} → {100, "Le"}
allora la lista sarà modificata così
{100, "LaLiLa"} → {110, "Lu"} → {105, "LoLa"} → {100, "LiLe"}