Corso di Laboratorio di Informatica Ingegneria Clinica BCLR Domenico Daniele Bloisi
Docente Ing. Domenico Daniele Bloisi, PhD Ricercatore Dipartimento di Ingegneria Informatica, Automatica e Gestionale Antonio Ruberti Via Ariosto 25 (adiacente Piazza Dante, fermate Manzoni, Vittorio Emanuele, Tram 3 fermata via Labicana) Email: bloisi@dis.uniroma1.it Home page: http://www.dis.uniroma1.it/~bloisi Pagina 2
Ricevimento In aula, subito dopo le lezioni Su appuntamento (tramite invio di una email) presso: Dipartimento di Ingegneria Informatica, Automatica e Gestionale Antonio Ruberti, via Ariosto 25 - II piano, stanza A209 Si invitano gli studenti a controllare regolarmente la bacheca degli avvisi http://www.dis.uniroma1.it/~bloisi/didattica/labinf1314.html#avvisi Pagina 3
Orari Lunedì 12.00 13.30 Aula 15, via Scarpa 14 Lunedì 14.00 17.15 Aula 15, Laboratorio Didattico via Tiburtina 205 Martedì 14.00 15.30 Aula 16, via Scarpa 14 Mercoledì 12.00 13.30 Aula 15, via Scarpa 14 Pagina 4
Sommario Array di caratteri: stringhe Inizializzazione di stringhe Lettura e scrittura di stringhe Operazioni sulle stringhe Funzioni per la manipolazione delle stringhe: strcpy, strncpy, strcat, strncat, strcmp, strstr Input/Output in C Stream Pagina 5
I/O in C Il sistema di I/O del C è una interfaccia uniforme per il programmatore. Scrivere o leggere da file o da video/tastiera non comporta differenze concettuali. Indipendentemente dal dispositivo di lettura e scrittura utilizzato, potranno essere utilizzate le medesime funzioni. Pagina 6
Schema di un calcolatore Tastiera Mouse Stampante Modem Porte I/O Controller dischi Hard disk CD/ROM DVD CPU Scheda video Monitor Memoria Scheda audio Casse Microfono bus Scheda rete Altro PC Internet Pagina 7
Sistema di I/O Il sistema di I/O del C permette di inserire un livello di astrazione tra il programmatore e l oggetto, sia esso un file o dispositivo, su cui (da cui) si vuole scrivere (leggere). L astrazione si ottiene attraverso la creazione di uno stream (flusso di dati) Pagina 8
Stream Uno stream (flusso di dati) fornisce un canale di comunicazione tra il programma e l esterno (file o device) Uno stream è una struttura costituita da una sequenza di byte terminante con un apposito carattere che ne identifica la fine. Pagina 9
Stream Gli stream possono essere associati (con opportuni comandi) Ai dispositivi fisici collegati al computer (tastiera, video, stampante, etc ) Ai file residenti sulla memoria di massa (disco fisso) Pagina 10
Bufferizzazione Gli streams di I/O sono bufferizzati Ogni volta che viene eseguita una operazione di I/O verrà letto (scritto) da (su) file un "pezzo" di dimensioni stabilite, utilizzando alcune aree temporanee di immagazzinamento Pagina 11
Bufferizzazione La bufferizzazione rende efficiente l'i/o, ma è necessario fare attenzione: i dati scritti in un buffer non compaiono nel file (o nel device) finché il buffer non è riempito o scaricato. Ad esempio, il carattere di escape '\n' forza lo svuotamento del buffer. Uscite anormali da un programma possono causare problemi se il buffer non viene opportunamente svuotato. Pagina 12
FILE Esiste una struttura di dati interna al C, FILE, che rappresenta uno stream ed è definita nel file stdio.h. Viene usato il nome FILE per motivi storici, anche se la struttura FILE può essere usata per rappresentare un oggetto diverso da un file in senso tecnico. E' sufficiente fare riferimento alla struttura FILE nei programmi C quando si realizza l'i/o utilizzando uno stream. Pagina 13
Esempio printf La funzione printf produce una sequenza di caratteri che viene inviata allo stream stdout (video) Pagina 14
Esempio scanf La funzione scanf legge i caratteri dallo stream stdin (tastiera), ossia lo stream di input, e li deposita, convertendoli nello specifico formato, nelle variabili il cui indirizzo è specificato come parametro Pagina 15
I file rappresentano la principale struttura per la memorizzazione di dati in maniera permanente su memoria di massa (hanno la caratteristica di sopravvivere allo spegnimento della macchina). Possono contenere Caratteri alfanumerici codificati in formato standard (es. ASCII) direttamente leggibili dall utente (file di testo) Dati in un formato interpretabile dai programmi (file binari) Pagina 16
Flusso sequenziale di byte delimitato dal carattere di terminazione chiamato End-Of- (EOF). Pagina 17
di testo I file di testo sono normalmente organizzati in sequenze di linee ciascuna delle quali contiene una sequenza di caratteri. In questo corso tratteremo solamente file di testo. Pagina 18
e directory Ogni file è caratterizzato da un nome e una directory (o cartella) in cui risiede. Le operazioni fondamentali sui file sono: creazione, lettura, scrittura, rinominazione ed eliminazione. Queste operazioni possono essere effettuate tramite il sistema operativo (o altri programmi applicativi) oppure mediante apposite istruzioni del linguaggio C. Pagina 19
Operazioni sui file Per eseguire operazioni di lettura e scrittura sui file è necessario Aprire il file prima di eseguire le operazioni Chiudere il file al termine dell esecuzione delle operazioni. Pagina 20
e stream Il file deve essere connesso al programma tramite l astrazione dello stream. Nel caso degli stream standard stdin, stdout, stderr l apertura e la chiusura avviene in maniera automatica Nel caso di FILE l apertura e la chiusura dello stream associato al file non sono automatici, ma vanno gestiti esplicitamente Pagina 21
Aprire un Aprire un file significa indicare al sistema operativo la volontà di eseguire operazioni sui file. Il sistema operativo verificherà, all atto dell apertura del file, se tale operazione è possibile. Pagina 22
Scrittura e lettura L apertura del file si distingue in due casi: 1. Apertura in lettura 2. Apertura in scrittura A seconda del tipo di apertura scelto, il sistema operativo definisce un comportamento differente Ad esempio, è possibile che due applicazioni aprano lo stesso file contemporaneamente in lettura, ma non in scrittura. In molti linguaggi di programmazione l apertura in scrittura di un file coincide con la sua creazione. Pagina 23
Le funzioni fprintf e fscanf fprintf ( <descrittore>, <stringa di controllo>, <altri-argomenti> ) fscanf ( <descrittore>, <stringa di controllo>, <altri-argomenti> ) Sono le versioni di printf e scanf relative ad un generico file esterno. Pagina 24
Descrittore di file <descrittore> È una connessione tra: il mondo interno al programma (tutto in memoria centrale) e il mondo esterno (rappresentato dai file residenti nelle memoria di massa) È legato al nome fisico del file e ad altre caratteristiche strutturali Pagina 25
Descrittore di file Per usare file esterni Si deve introdurre questo rappresentante interno del mondo esterno (descrittore) Si deve creare una associazione temporanea tra mondo esterno e rappresentante interno Pagina 26
Sintassi - Descrittore di Il descrittore di file è una variabile Bisogna specificare un nome e un tipo per poterlo dichiarare FILE *<identificatore>; Esempio FILE *ingressodsc; Pagina 27
Puntatore a FILE FILE *ingressodsc; FILE * si riferisce ad uno specifico tipo puntatore a file esterno ingressodsc è una variabile di tipo puntatore a FILE Attenzione: non basta dichiarare un descrittore del file, bisogna anche creare il legame con l esterno Pagina 28
Le funzioni fprintf e fscanf int fprintf ( FILE * stream, const char * format,... ); int fscanf ( FILE * stream, const char * format,... ); Sono definite in stdio.h Pagina 29
Connessione La funzione fopen crea la connessione tra il descrittore e il file vero e proprio (esterno) <descrittore> = fopen( <nomefileesterno>, <modalità di uso> ); Esempio ingressodsc = fopen("filedaleggere.txt", "r"); Pagina 30
Modalità d uso Si deve specificare se il file va usato in lettura o in scrittura (si ricordi la distinzione tra stdin e stdout ) in lettura "r" (read) in scrittura "w" (write) Scrittura alla fine del file "a" (append) Pagina 31
Esempio FILE *uscitadsc; uscitadsc = fopen("filedascrivere.txt", "w"); Pagina 32
Chiusura della connessione Quando il file esterno non serve più, deve essere chiuso Questo si ottiene cancellando esplicitamente la connessione con l esterno fclose(<descrittore>); Pagina 33
Esempio int main() { //dichiarazioni dei descrittori FILE *inputdsc; FILE *outputdsc; inputdsc = fopen("filedatiingresso", "r") outputdsc = fopen("filedatiuscita.txt", "w") fclose(inputdsc); fclose(outputdsc); } Pagina 34
Eccezioni Nella comunicazione con il mondo esterno può accadere che il file non si apra correttamente. Questo viene segnalato da un valore particolare del descrittore di file, indicato con NULL. Dopo fopen( ) inserire sempre un controllo if (inputdsc == NULL) { //gestione dell errore... } Pagina 35
Esempi if (inputdsc == NULL) printf("errore nella apertura del " "file di ingresso"); if (outputdsc == NULL) printf("errore nella apertura del " "file di uscita"); Pagina 36
Modello ideale per il Un file può essere immaginato come un nastro contenente informazioni. Il descrittore può essere visto come una testina mobile che punta ad una cella del nastro. La testina viene spostata da istruzioni come fscanf e fprintf testina Pagina 37
La fine del file (EOF) La fine del file viene segnalata da un carattere particolare, il simbolo di End-of- (EOF) La codifica del carattere EOF dipende dalla macchina Ctrl-z per Windows Ctrl-d per Mac Ctrl-x per Unix e Linux Pagina 38
Riassumendo 1. Viene dichiarato il descrittore del file FILE *<descrittore>; 2. Il file si apre con la funzione fopen <descrittore> = fopen( <nome_file>, <modo_apertura ); <nome_file> è il nome fisico del file, cioè il nome con cui il file è chiamato sul disco, es. dati.txt <modo_apertura>: "w" se il file è aperto in scrittura "r" se il file è aperto in lettura Pagina 39
Riassumendo 3. Possono essere eseguite operazioni di lettura e scrittura utilizzando il descrittore del file 4. Il file viene chiuso fclose(<descrittore>); Pagina 40
Esempio FILE *fp; fp = fopen("test.dat", "r"); FILE *fptr; fptr = fopen("prova.dat", "w"); //lettura utilizzando fp e //scrittura utilizzando fptr fclose(fp); fclose(fptr); Pagina 41
Esercizio Leggere un file di testo esempio.txt e stampare ogni parola in una singola riga esempio.txt Contenuto del file di testo. Output Contenuto del file di testo. Pagina 42
Condizioni sull input Deve esistere già un file che possa essere aperto in lettura e analizzato per produrre il risultato desiderato. Pagina 43
Soluzione #include <stdio.h> #include <stdlib.h> int main (){ char ch; FILE *fd; //descrittore del file fd = fopen("esempio.txt", "r"); if(fd == NULL){ printf("\nerrore di apertura!\n"); return EXIT_FAILURE; } while (fscanf(fd, "%c", &ch)!= EOF) { if(ch == ' ') printf("\n"); else printf("%c", ch); } fclose(fd); return EXIT_SUCCESS; } Pagina 44
Valore di ritorno per scanf int fscanf ( FILE * stream, const char * format,... ); fscanf restituisce un valore che è pari ad EOF quando viene raggiunta la fine del file Pagina 45
Operatori per leggere e scrivere caratteri Leggere da tastiera e scrivere a video getchar (lettura) putchar (scrittura) Leggere da file e scrivere su file fgetc(<filedescrittore>); fputc(<intero>, <filedescrittore>); Pagina 46
Esempio while((ch = fgetc(fd))!= EOF) { if(ch == ' ') putchar('\n'); else putchar(ch); } Pagina 47
Esercizio scrittura su file Memorizzare su un file clienti.txt i seguenti dati: Numero di conto Bilancio per un massimo di 10 clienti inseriti da tastiera. Digitare EOF per terminare prima l inserimento. Pagina 48
Soluzione scrittura su file int main () { int conto, i; float bilancio; FILE *cfptr; /* descrittore file */ if ((cfptr = fopen("clienti.txt", "w")) == NULL) { printf("il file non puo\' essere aperto"); return EXIT_FAILURE; } for (i=1; i<=10; i++) { printf("immetti il conto e il bilancio\n"); if(scanf("%d%f", &conto, &bilancio) == EOF) break; fprintf(cfptr, "%d %f\n", conto, bilancio); } fclose(cfptr); return EXIT_SUCCESS; } Pagina 49
Esecuzione Immetti il conto e il bilancio 23 456 Immetti il conto e il bilancio 12 8764 Immetti il conto e il bilancio 90-78 Immetti il conto e il bilancio ^Z clienti.txt 23 456.000000 12 8764.000000 90-78.000000 Pagina 50
Esercizio lettura da file Leggere dal file clienti.txt i seguenti dati: Numero di conto Bilancio Pagina 51
Soluzione lettura da int main () { int conto, i; float bilancio; FILE *cfptr; // descrittore file if ((cfptr = fopen("clienti.txt", "r")) == NULL) printf("il file non puo\' essere aperto\n"); return EXIT_SUCCESS; } printf("conto \t\t Bilancio\n"); for (i=1; i<=10; i++) { if(fscanf(cfptr,"%d%f",&conto,&bilancio) == EOF) break; printf("%d \t\t %f\n", conto, bilancio); } fclose(cfptr); return EXIT_SUCCESS; } Pagina 52
Esecuzione Conto Bilancio 23 456.000000 12 8764.000000 90-78.000000 Pagina 53