Strumenti Utente

Strumenti Sito


fisica:informatica:201819:esercitazioni:esercitazione12sel

Esercizi strutture, stringhe e file

Esercizio 1: Archivio studenti

Scrivere un programma C che legge una sequenza di studenti dal file anagrafe_studenti.txt. Ogni studente e' memorizzato su file in una singola linea contenente tre stringhe di caratteri separate da ':' e terminata da '\n' secondo il formato

cognome:nome:numero_di_matricola

quindi ad esempio

...
Rossi:Mario:234445
Bixio:Nino:435678
Garibaldi:Giuseppe:787899
...

Il programma legge da file gli studenti e memorizza i dati relativi a ciascun studente in un array di strutture di tipo:

#define N 50
 
typedef struct {
  char nome[N+1];
  char cognome[N+1];
  unsigned matricola;
  } studente_t;

L'array viene poi ordinato per il campo cognome e nel caso di cognomi uguali per il campo nome e poi stampato sullo standard output.

Suggerimento: Per la lettura da file usare fscanf() con una opportuna stringa di formattazione oppure fgets() per leggere fino al primo \n e strchr() per localizzare i caratteri separatori :

Esercizio 2: La linea di comando: ''argc'' e ''argv''

In C e' possibile accedere agli argomenti passati sulla linea di comando tramite la i parametri della funzione main che puo' essere dichiarata di tipo :

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

in questo modo all'attivazione argc contiene il numero di argomenti passati sulla linea di comando, e l'array di stringhe argv contiene tutte le parole trovate sulla linea di comando usando come separatori lo spazio bianco (' ') e il tab ('\t'). Ad esempio, se ho compilato il mio programma in un eseguibile prova e l'ho attivato con il comando

bash$ ./prova pippo pluto paperone

argc varra' 4, argv[0] conterra' ./prova, argv[1] conterra' pippo, argv[2] pluto ed argv[3] paperone.

Scrivere un programma C che stampa sullo standard output il numero di argomenti e tutte le parole sulla linea di comando separate da un newline ('\n'), ad esempio

bash$ ./prova pippo pluto paperone
./prova ha 3 argomenti
pippo
pluto
paperone

Esercizio 3: Leggere il file anagrafe da linea di comando

Modificare la soluzione dell'esercizio 1 in modo da leggere il nome del file di anagrafe da linea di comando e da poter specificare opzionalmente il nome del file in cui scrivere la sequenza ordinata di studenti. Cioe'

bash$ ./leggistud nome_file [-o out_file]

legge gli studenti dal file nome_file passato come primo parametro. Se specificato un file per l'output (opzione -o) l'elenco degli studenti viene stampato su file invece che su standard output.

Fare in modo di stampare un opportuno messaggio di uso se leggistud e' attivato con un numero di parametri diverso da 2 o in modo sbagliato.

Approfondimenti: provare ad utilizzare la funzione di libreria getopt (man 3 getopt) per eseguire l'analisi (parsing) della linea di comando. Questa funzione e' realmente utilizzata per analizzare la linea di comando dei comandi di shell che utilizziamo normalmente.

Esercizio 4: Problema della corrispondenza di Post

Sia P un array di 'tessere di domino' P[1] …. P[N-1]. Ogni tessera a = P[i] e' una struct che contiene due campi di tipo stringa (char *), top e bottom:

typedef struct tessera {
	char * top;
	char * bottom;
} tessera_t;

Un 'match' e' una sequenza di tessere a_1, a_2, … a_k (possibilmente con ripetizioni di tessere) tale che la sequenza “a_1.top a_2.top … a_k.top” ottenuta concatenando tutti i campi top sia uguale alla sequenza “a_1.bottom a_2.bottom … a_k.bottom” ottenuta concatenando tutti i bottom.

Esempio:

P[0] = { "c" , "ci" };
P[1] = { "i" , "a" };
P[2] = { "ao" , "o" }; 
P[3] = { "a" , "a" };

P[0],P[1],P[2] e' un match: concatenando tutti i campi top otteniamo “c”,“i”,“ao” = “ciao”, e ugualmente ottenamo “ci”,“a”,“o” = “ciao” concatenando tutti i campi bottom.

Anche P[0],P[1],P[3],P[3],P[3],P[3],P[2] e' un match! otteniamo “c”,“i”,“a”,“a”,“a”,“a”,“ao” (top) e “ci”,“a”,“a”,“a”,“a”,“a”,“o” (bottom).

Invece, se l'array e':

P[0] = { "a" , "1" };
P[1] = { "b" , "2" };

Chiaramente non esiste alcun match.

Si scriva una funzione int post(tessera_t * P, int n) che prenda in input un array di n tessera_t, e ritorni 1 se e' possibile trovare un qualsiasi 'match' in P, o 0 altrimenti.

Suggerimento: prima di cominciare a scrivere codice, ragionare su come si puo' fare per stabilire se esiste o meno un match.

fisica/informatica/201819/esercitazioni/esercitazione12sel.txt · Ultima modifica: 01/04/2019 alle 13:58 (20 mesi fa) da Alessio Conte