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

Slides:



Advertisements
Presentazioni simili
File Linguaggio C.
Advertisements

Puntatori Linguaggio C.
Fondamenti di Informatica CDL in Ingegneria Gestionale - A.A Gestione dei file Ing. Simona Colucci.
INFORMATICA Algoritmi fondamentali
Uso avanzato di C.
1 Informatica Generale Susanna Pelagatti Ricevimento: Mercoledì ore presso Dipartimento di Informatica, Via Buonarroti,
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Fondamenti di Informatica I CDL in Ingegneria Elettronica - A.A CDL in Ingegneria Elettronica - A.A Strutture dati dinamiche.
Introduzione al linguaggio C
Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
Grafi Algoritmi e Strutture Dati. Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano Algoritmi e strutture dati 2/ed 2 Copyright © The McGraw.
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
1 System Call per Comunicazione tra Processi Pipe.
Università La Sapienza Web programming e programmazione multimediale 1 Web Programming e comunicazione multimediale Lezione 10: PHP.
INFORMATICA I file.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Liste.
FILE DATI 16 lunedi 26 luglio giovedi ore 9 Come sappiamo, un file dati è un gruppo di informazioni tra loro correlate, memorizzate in un dispositivo di.
PROGRAMMI DI RICERCA E ORDINAMENTO
Esercizi su alberi binari
Tail recursion: esempio
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE File Marco D. Santambrogio – Ver. aggiornata al 15 Maggio 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE File Marco D. Santambrogio – Ver. aggiornata al 9 Maggio 2012.
File.
Laboratorio di Linguaggi lezione VI: puntatori 2/3 Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso.
Laboratorio di Linguaggi P R I M O C O M P I T I N O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese.
Laboratorio di Linguaggi lezione XI: I/O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea.
Esercizi su alberi binari
INFORMATICA I file. © Piero Demichelis 2 File Per rendere più uniforme possibile il comportamento dei programmi in relazione alla grande varietà dei dispositivi.
Esercizio: Copiare un file in un nuovo file mediante le funzioni read e write.
Struct, enum, Puntatori e Array dinamici
1 Strutture Dinamiche Corso di Informatica A Vito Perrone.
Strutture di controllo nel C
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Strutture di controllo in C -- Flow Chart --
Esercizi C sui tipi definiti dall’utente
Politecnico di Milano Esercizi Stringhe Ricerca binaria.
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Politecnico di Milano Esercizi Preparazione alla prima prova intermedia.
1 Gestione dei File Corso di Informatica A Vito Perrone.
File di testo, file binari
Esercizi C su array e matrici
Dichiarazioni e tipi predefiniti nel linguaggio C
Le liste dinamiche La ricorsione
I File.
Introduzione alle basi di dati
GESTIONE DEI FILE Per poter mantenere disponibili i dati tra le diverse esecuzioni di un programma (persi-stenza dei dati) è necessario poterli archi-viare.
1.Scrivere una funzione per cercare un numero x in una lista circolare di interi. La funzione deve restituire NULL se il numero non esiste. 2.Scrivere.
1 ListaDiElem Cancella( ListaDiElem lista, TipoElemento elem ) { ListaDiElem puntTemp; if( ! ListaVuota(lista) ) if( lista–>info == elem ) { puntTemp =
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
1 Gestione dei File. 2 Perché i file? Sono strutture dati persistenti Sono solitamente memorizzati sui dischi –Si usano dall'interno dei programmi Realizzano.
Unità Didattica 3 Linguaggio C
21 marzo 2002 (ri-)Avvisi: Giovedi 28 marzo la lezione e sospesa. Nuovo indirizzo di Spedire messaggi e esercizi solo.
C. Gaibisso Programmazione di Calcolatori Lezione XXII La struttura di dati lista di variabili strutturate Programmazione di Calcolatori: le liste di.
Esercizi su File.
Esercizi Liste.
Esercizi su File e Liste
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Gestione dei file di testo, matrici e struct
2000 Prentice Hall, Inc. All rights reserved. Capitolo 11 (Deitel) Lelaborazione dei file Sommario Introduzione La gerarchia dei dati 11.3.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Grafi Rappresentazione mediante liste di adiacenza:
ALGORITMI Un algoritmo è un insieme di istruzioni: -ordinate -non ambigue -effettivamente computabili.
Programmazione in linguaggio C
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE File Marco D. Santambrogio – Ver. aggiornata al 21 Maggio 2014.
Fabio Scotti – Università degli Studi – Laboratorio di programmazione per la sicurezza 1 Lezione 13 e 14 GESTIONE DEI FILE A) Nozioni sulla gestione dei.
1 Fabio Scotti ( ) Laboratorio di programmazione per la sicurezza Valentina Ciriani ( ) Laboratorio di programmazione Lezione 13 e 14 -
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Capitolo 14 Diapositiva 1 Linguaggio C – Guida alla programmazione 2/ed – A. Bellini, A. Guidi Copyright © The McGraw-Hill Companies srl Archiviare.
13. Strutture dati dinamiche Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
1 MODULO STRUTTURE DATI FONDAMENTALI: Strutture dinamiche classe 4° INDUSTRIALE INFORMATICA Focus on.
Transcript della presentazione:

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

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.

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; .

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'; } .

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

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); } .

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); } .

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 >

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; }

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); }

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);

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); }

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?

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;

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;

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);

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);

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

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); }

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 */

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);

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;

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);

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; }

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);

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().

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);

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().

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

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.

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

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

Le liste dinamiche

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

Le liste dinamiche: definizione #include <stdio.h> #include <stdlib.h> struct Elem { int dato; struct Elem *prox; }; typedef struct Elem ElementoLista; typedef ElementoLista *Lista;

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à.

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);

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);

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.

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; }

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

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.

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;

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;

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

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() ?

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;

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!

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");

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!!!