La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Politecnico di Milano Esercizi Esercizi di riepilogo sul linguaggio C: file, puntatori, liste.

Presentazioni simili


Presentazione sul tema: "Politecnico di Milano Esercizi Esercizi di riepilogo sul linguaggio C: file, puntatori, liste."— Transcript della presentazione:

1 Politecnico di Milano Esercizi Esercizi di riepilogo sul linguaggio C: file, puntatori, liste

2 - 2 - Codifica file di testo Utilizzando la codifica di Cesare, scrivere un programma in grado di criptare e decriptare un file di testo Il programma chiederà allutente il nome del file da elaborare, il nome del file in cui scrivere il risultato, loperazione da effettuare (codifica o decodifica) ed il codice.

3 - 3 - Codifica file di testo #include const unsigned int CRIPTA = 0; const unsigned int DECRIPTA = 1; void codificaCesare (char *car, unsigned int k, unsigned int azione) { int temp;.

4 - 4 - Codifica file di testo if (azione == CRIPTA) { *car = *car - 'a'; temp = *car + k; if (temp < 26) { *car = temp; } else { *car = temp - 26; } *car = *car + 'a'; }.

5 - 5 - Codifica file di testo else /* decripta */ { *car = *car - 'a'; temp = *car - k; if (temp >= 0) { *car = temp; } else { *car = temp + 26; } *car = *car + 'a'; } }.

6 - 6 - Codifica file di testo void codificaFile(char nFileIn[], char nFileOut[], unsigned int cod, unsigned int oper) { FILE *fileIn, *fileOut; char car; fileIn = fopen (nFileIn, "r"); fileOut = fopen (nFileOut, "w"); fscanf (fileIn, "%c", &car); while (!feof(fileIn)) { codificaCesare (&car, cod, oper); fprintf (fileOut, "%c", car); fscanf (fileIn, "%c", &car); } fclose (fileIn); fclose (fileOut); }.

7 - 7 - Codifica file di testo void main() { char nomeFileIn[100], nomeFileOut[100]; unsigned int codice, operazione; printf ("File input: "); scanf ("%s", nomeFileIn); printf ("File output: "); scanf ("%s", nomeFileOut); printf ("Codice: "); scanf ("%u", &codice); printf ("0=cripta, 1=decripta: "); scanf ("%u", &operazione); codificaFile (nomeFileIn, nomeFileOut, codice, operazione); }.

8 - 8 - Elimina tag HTML Il programma legge un file di testo contenente una pagina HTML, elimina i tag presenti e salva il testo in un altro file. I tag scartati saranno visualizzati sul monitor. Miglioramenti: Scrivere solo il testo che si trova in … Scrivere i tag in modo più leggibile: uso sotto laltro con i simboli

9 - 9 - Elimina tag HTML #include void eliminaTag (char nomeFileHTML[], char nomeFileTesto[]) { typedef enum {tag, testo, errore} TipoStato; FILE *docHTML, *docTesto; char car; TipoStato stato = testo; docHTML = fopen (nomeFileHTML, "r"); if (docHTML == NULL) { printf ("File %s non trovato\n", nomeFileHTML); return; }

10 Elimina tag HTML docTesto = fopen (nomeFileTesto, "w"); fscanf (docHTML, "%c", &car); while (!feof(docHTML) && stato != errore) { if (stato == testo) { switch (car) { case '<': stato = tag; break; case '>': stato = errore; break; default: fprintf (docTesto, "%c", car); break; } }

11 Elimina tag HTML else if (stato == tag) { switch (car) { case '<': stato = errore; break; case '>': stato = testo; break; default: printf ("%c", car); break; } } fscanf (docHTML, "%c", &car); } fclose (docTesto); fclose (docHTML); }

12 Elimina tag HTML void main() { char nomeFileHTML[255], nomeFileTesto[255]; printf ("Nome file HTML: "); scanf ("%s", nomeFileHTML); printf ("Nome file testo: "); scanf ("%s", nomeFileTesto); eliminaTag (nomeFileHTML, nomeFileTesto); }

13 Archivio film Il programma dovrà permettere allutente, tramite un menù, di gestire un archivio di film Dovranno essere disponibili le seguenti operazioni: 1. Lutente inserisce un certo numero di film: Codice identificativo numerico e titolo (senza spazi) Linserimento della lista di film è terminato immettendo uno codice pari a zero 2. Lutente inserisce un codice e lelaboratore verifica se il corrispondente film è presente nel file (ed in questo caso ne scrive i dati sul monitor) Utilizzare lalgoritmo di ricerca binaria e lalgoritmo bubble-sort E se usassimo lordinamento per inserzione?

14 Archivio film: ricerca binaria 0 Valore della variabile inizio 2 Valore della variabile fine 1 Valore della variabile medio fseek (archivio, -sizeof(Film), SEEK_END); Posizione iniziale allapertura del file Posizione dopo fseek() inizio = 0; fine = ftell(archivio) / sizeof(Film); medio = (inizio + fine) / 2; archivio = fopen ("pippo", "rb");

15 Archivio film #include typedef struct { unsigned int codice; char titolo[100]; } Film; void ordina (char nomeFile[]) { typedef enum {falso, vero} Booleano; FILE *archivio; Film filmCorrente, filmSuccessivo; unsigned int numFilm, i; Booleano scambio;

16 Archivio film /* "r+b" permette di leggere/scrivere su file binario esistente */ archivio = fopen (nomeFile, "r+b"); fseek (archivio, -sizeof(Film), SEEK_END); /* calcola numero di film inseriti nel file */ numFilm = ftell (archivio) / sizeof(Film) + 1 ; do { scambio = falso; /* si riporta a inizio file */ fseek (archivio, 0, SEEK_SET);

17 Archivio film for (i = 0; i < numFilm - 1; i++) { fread (&filmCorrente, sizeof(Film), 1, archivio); fread (&filmSuccessivo, sizeof(Film), 1, archivio); if (filmCorrente.codice > filmSuccessivo.codice) { /* sposta testina due record all'indietro */ fseek(archivio,-2*sizeof(Film), SEEK_CUR); fwrite (&filmSuccessivo, sizeof(Film),1, archivio);

18 Archivio film fwrite (&filmCorrente, sizeof(Film), 1, archivio); scambio = vero; } } } while (scambio); fclose (archivio); }

19 Archivio film void inserisci (char nomeFile[]) { FILE *archivio; Film nuovoFilm; /* apertura file per scrivere in append */ archivio = fopen (nomeFile, "ab"); printf ("Codice film diverso da 0: "); scanf ("%u", &nuovoFilm.codice); if (nuovoFilm.codice != 0) { printf ("Titolo film: "); scanf ("%s", nuovoFilm.titolo); }

20 Archivio film while (nuovoFilm.codice != 0) { fwrite (&nuovoFilm, sizeof(nuovoFilm), 1, archivio); printf ("Codice film diverso da 0: "); scanf ("%u", &nuovoFilm.codice); if (nuovoFilm.codice != 0) { printf ("Titolo film: "); scanf ("%s", nuovoFilm.titolo); } } fclose (archivio); ordina (nomeFile); /* riordina tutto il file */ }

21 Archivio film void cerca (char nomeFile[]) { typedef enum {falso, vero} Booleano; Booleano trovato = falso; FILE *archivio; Film filmCorrente; unsigned int codCercato; int inizio, fine, medio; printf ("Codice cercato: "); scanf ("%u", &codCercato); archivio = fopen (nomeFile, "rb"); inizio = 0; fseek (archivio, -sizeof(Film), SEEK_END); fine = ftell (archivio) / sizeof(Film);

22 Archivio film do { medio = (inizio + fine) / 2; fseek (archivio, medio * sizeof(Film), SEEK_SET); fread (&filmCorrente, sizeof(filmCorrente), 1, archivio); if (codCercato < filmCorrente.codice) { fine = medio - 1; } else if (codCercato > filmCorrente.codice) { inizio = medio + 1; }

23 Archivio film else { trovato = vero; } } while (!trovato && inizio <= fine); if (trovato) { printf ("Trovato in posiz: %u\n", medio); printf("Codice: %u\n",filmCorrente.codice); printf("Titolo: %s\n",filmCorrente.titolo); } else { printf ("Non trovato!\n"); } fclose (archivio); }

24 Archivio film unsigned int menu () { unsigned int scelta; printf ("1. Inserisci elenco film\n"); printf ("2. Cerca film\n"); printf ("3. Esci\n"); printf ("\nScelta: "); scanf ("%u", &scelta); return scelta; }

25 Archivio film void main() { char nomeArchivio[] = "numeri.dat"; unsigned int n; do { n = menu(); switch (n) { case 1: inserisci (nomeArchivio); break; case 2:cerca (nomeArchivio); break; } } while (n != 3); }

26 Riepilogo sui file… Le funzioni fscanf(), fread(), fprintf(), fwrite() leggono/scrivono a partire dalla posizione corrente della testina allinterno del file Dopo loperazione, la testina si sposta in avanti di una quantità di byte pari al numero di byte letti/scritti Il tipo del dato letto dal file deve essere in accordo con quanto la funzione si aspetta: Se un file contiene una stringa e lo leggo con: fscanf (file, " %d ", &varIntera); la variabile varIntera conterrà un valore scorretto! Idem per quanto riguarda fread().

27 Riepilogo sui file… Uso di sizeof() con fread() e fwrite() : Quando leggo/scrivo variabili che non siano vettori, uso il nome della variabile: int v; fread (&v, sizeof(v), 1, ilfile); Quando leggo/scrivo variabili vettore, uso: Il nome della variabile, per leggere/scrivere tutto il vettore in un colpo solo: int vet[10]; fread (vet, sizeof(vet), 1, ilfile); Il nome del tipo, per leggere/scrivere solo una cella del vettore: int vet[10], i = 0; fread (&vet[i], sizeof(int), 1, ilfile);

28 Riepilogo sui file… File di testo o binari? Quando è richiesto di leggere/scrivere delle variabili strutturate, si usano i file binari Quando è richiesto di spostarsi allinterno del file ( fseek() ), si usano i file binari Quando è richiesto di leggere/scrivere stringhe di caratteri, si usano (tipicamente) file di testo Quando scrivo con fprintf(), leggo con fscanf(), quando scrivo con fwrite(), leggo con fread().

29 Puntatori char *p, s[]=xyz; p = s; int *p2; p2 = 23; oppure… int *p3; *p3 = 23; oppure… int *p4, var; p4 = &var; *p4 = 23; ? 23 p2 Indirizzo: p4 var 23 p3 99 Indirizzo: 99 Es. di valore casuale \0zyx p s

30 Puntatori Dato il seguente frammento di programma C: int *p1, *p2, x, y; x = 10; y = 20; p1 = &x; p2 = p1; *p1 = 5; p2 = &y; y = 30; *p2 = *p1 + *p2; *p1 = *p1 + x; Disegnare il valore di tutte le variabili al termine dellesecuzione di ogni riga. Le variabili x e y si trovano, rispettivamente, nelle celle di memoria di indirizzo 1000 e 2000.

31 Puntatori int *p1, *p2, x, y; x = 10; y = 20; p1 = &x; p2 = p1; ?????10??? 20? ? p1xyp

32 Puntatori *p1 = 5; p2 = &y; y = 30; *p2 = *p1 + *p2; *p1 = *p1 + x; p1xyp

33 Le liste dinamiche

34 Le liste dinamiche: operazioni tipiche Inserimento di un elemento: In testa alla lista In coda alla lista In un punto generico (equivale ad inserire in testa ad una sotto-lista) Cancellazione di un elemento: Dalla testa Dalla coda Da un punto generico (equivale a cancellare la testa di una sotto-lista) Cancellazione totale della lista Ricerca Stampa della lista Ordinamento

35 Le liste dinamiche: definizione #include struct Elem { int dato; struct Elem *prox; }; typedef struct Elem ElementoLista; typedef ElementoLista *Lista;

36 Le liste dinamiche: libreria di funzioni Lista inserisciInTesta (Lista lista, int dato); Lista inserisciInCoda (Lista lista, int dato); Lista cancellaTesta (Lista lista); Lista cancellaCoda (Lista lista); Lista cancellaLista (Lista lista); Lista cercaInLista (Lista lista, int dato); void scriviLista (Lista lista); In un caso reale, sostituirò int con il tipo che mi interessa Per esempio, potrei definire il tipo CartaIdentita e costruire quindi un lista di carte di identità.

37 Le liste dinamiche: il main void main() { unsigned int num, i; int d, cercato; Lista laMiaLista, elem; /* Nessuna limitazione a priori! */ printf ("Quanti dati? "); scanf ("%u", &num); for (i = 0; i < num; i++) { printf ("Dato: "); scanf ("%d", &d); laMiaLista=inserisciInCoda(laMiaLista,d); } printf ("Dato da cercare: "); scanf ("%d", &cercato);

38 Le liste dinamiche: il main scriviLista(laMiaLista); elem = cercaInLista (laMiaLista, cercato); if (elem != NULL) { printf ("Dato cercato: %d\n", elem->dato); } else { printf ("Dato non trovato\n"); } laMiaLista = cancellaTesta (laMiaLista); scriviLista(laMiaLista); laMiaLista = cancellaCoda (laMiaLista); scriviLista(laMiaLista); laMiaLista = cancellaLista (laMiaLista); scriviLista(laMiaLista); }

39 Le liste dinamiche: inserisci in testa Lista inserisciInTesta (Lista lista, int dato) { Lista nuovoElem; nuovoElem=(Lista)malloc(sizeof(ElementoLista)); nuovoElem->dato = dato; nuovoElem->prox = lista; return nuovoElem; } Dopo ogni inserimento, lista (il puntatore alla testa della lista) viene modificato.

40 Le liste dinamiche: inserisci in coda Lista inserisciInCoda (Lista lista, int dato) { Lista nuovoElem, cursore; nuovoElem=(Lista)malloc(sizeof(ElementoLista)); nuovoElem->dato = dato; nuovoElem->prox = NULL; if (lista == NULL) return nuovoElem; else { cursore = lista; while (cursore->prox != NULL) cursore = cursore->prox; cursore->prox = nuovoElem; return lista; } }

41 Le liste dinamiche: inserisci in coda Due casi: Lista vuota il nuovo elemento è il primo della lista; la funzione ne ritorna lindirizzo Lista non vuota arriva allultimo elemento e vi appende il nuovo. Nel secondo caso, lista non viene modificato La funzione deve comunque ritornare qualcosa: ritorna lista

42 Le liste dinamiche: cancella la testa Lista cancellaTesta (Lista lista) { Lista temp; temp = lista->prox; free (lista); return temp; } Dopo ogni cancellazione, lista (il puntatore alla testa della lista) viene modificato.

43 Le liste dinamiche: cancella la coda Lista cancellaCoda (Lista lista) { Lista cursore; if (lista == NULL) { return lista; } else if (lista->prox == NULL) { free (lista); return NULL; }

44 Le liste dinamiche: cancella la coda else { cursore = lista; while (cursore->prox->prox != NULL) { cursore = cursore->prox; } free (cursore->prox); cursore->prox = NULL; return lista; } }

45 Le liste dinamiche: cancella la coda Tre casi: Lista già vuota non fa nulla Lista composta da un solo elemento la testa punta a NULL Lista composta da più elementi il penultimo punta a NULL

46 Le liste dinamiche: cancellazione totale Lista cancellaLista (Lista lista) { Lista temp, cursore; cursore = lista; while (cursore != NULL) { temp = cursore->prox; free (cursore); cursore = temp; } return cursore; } Come potrei definirla usando le funzioni cancellaTesta() o cancellaCoda() ?

47 Le liste dinamiche: ricerca Lista cercaInLista (Lista lista, int dato) { Lista cursore; int trovato = 0; cursore = lista; while (cursore != NULL && trovato == 0) { if (cursore->dato == dato) trovato = 1; else cursore = cursore->prox; } if (trovato == 1) return cursore; else return NULL; }

48 Le liste dinamiche: ricerca Ricerca lineare: parto dal primo elemento e vado avanti Non molto efficiente (la ricerca binaria è molto più veloce) Ma, posso fare diversamente? Liste accesso sequenziale!

49 Le liste dinamiche: scrivi lista void scriviLista (Lista lista) { Lista cursore; printf ("Inizio lista\n"); cursore = lista; while (cursore != NULL) { printf ("%d\n", cursore->dato); cursore = cursore->prox; } printf ("Fine lista\n"); }


Scaricare ppt "Politecnico di Milano Esercizi Esercizi di riepilogo sul linguaggio C: file, puntatori, liste."

Presentazioni simili


Annunci Google