La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Esercizi di riepilogo sul linguaggio C: file, puntatori, liste

Presentazioni simili


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

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

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à all’utente il nome del file da elaborare, il nome del file in cui scrivere il risultato, l’operazione da effettuare (codifica o decodifica) ed il codice.

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

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 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 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); } fclose (fileIn); fclose (fileOut); }

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 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 <body>…</body> Scrivere i tag in modo più leggibile: uso sotto l’altro con i simboli < e >

9 Elimina tag HTML #include <stdio.h>
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; default: fprintf (docTesto, "%c", car); }

11 Elimina tag HTML else if (stato == tag) { switch (car)
case '<': stato = errore; break; case '>': stato = testo; default: printf ("%c", car); } 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 all’utente, tramite un menù, di gestire un archivio di film Dovranno essere disponibili le seguenti operazioni: 1. L’utente inserisce un certo numero di film: Codice identificativo numerico e titolo (senza spazi) L’inserimento della lista di film è terminato immettendo uno codice pari a zero 2. L’utente inserisce un codice e l’elaboratore verifica se il corrispondente film è presente nel file (ed in questo caso ne scrive i dati sul monitor) Utilizzare l’algoritmo di ricerca binaria e l’algoritmo bubble-sort E se usassimo l’ordinamento per inserzione?

14 Archivio film: ricerca binaria
Valore della variabile inizio 1 Valore della variabile medio 2 Valore della variabile fine 102 203 101 204 305 306 Posizione iniziale all’apertura del file Posizione dopo fseek() archivio = fopen ("pippo", "rb"); fseek (archivio, -sizeof(Film), SEEK_END); inizio = 0; fine = ftell(archivio) / sizeof(Film); medio = (inizio + fine) / 2;

15 Archivio film #include <stdio.h> 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), , archivio); fread (&filmSuccessivo, sizeof(Film), , 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), , 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); 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); } } while (n != 3);

26 Riepilogo sui file… Le funzioni fscanf(), fread(), fprintf(), fwrite() leggono/scrivono a partire dalla posizione corrente della “testina” all’interno del file Dopo l’operazione, 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 all’interno 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; s int *p2; p2 = 23; oppure…
\0 z y x p s ? 23 p2 Indirizzo: 23 int *p2; p2 = 23; oppure… int *p3; *p3 = 23; int *p4, var; p4 = &var; *p4 = 23; 23 p3 99 Indirizzo: 99 Es. di valore casuale 23 p4 var

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 dell’esecuzione di ogni riga. Le variabili x e y si trovano, rispettivamente, nelle celle di memoria di indirizzo 1000 e 2000.

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

32 Puntatori p1 x y p2 1000 2000 *p1 = 5; p2 = &y; y = 30; *p2 = *p1 + *p2; *p1 = *p1 + x; 1000 5 20 1000 5 20 2000 1000 5 30 2000 1000 5 35 2000 1000 10 35 2000

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 <stdio.h> #include <stdlib.h> 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); laMiaLista = cancellaCoda (laMiaLista); laMiaLista = cancellaLista (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 l’indirizzo Lista non vuota  arriva all’ultimo 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; 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");

50 Le liste dinamiche: conclusione
Allocazione dinamica  il programmatore non è obbligato a porre dei limiti al numero di dati da memorizzare in RAM Prendo spazio quando serve, usando la malloc() Libero spazio quando posso, usando la free() Scomodo  i vettori sono più facili da usare Non esistono pasti gratis!!! Accesso solo sequenziale Idem come sopra!!!


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

Presentazioni simili


Annunci Google