Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR Domenico Daniele Bloisi Si ringrazia Raffaele Nicolussi
Docenti Parte I prof. Silvio Salza salza@dis.uniroma1.it http://www.dis.uniroma1.it/~salza/fondamenti.htm Parte II ing. Domenico Daniele Bloisi bloisi@dis.uniroma1.it http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1011.html Nota: %7E corrisponde alla tilde ~ Pagina 2
Informazioni Generali ing. Domenico Daniele Bloisi, PhD Dipartimento di Informatica e Sistemistica Via Ariosto 25 (adiacente Piazza Dante, A fermate Manzoni, Vittorio Emanuele, Tram 3 fermata via Labicana) mailto:bloisi@dis.uniroma1.it http://www.dis.uniroma1.it/~bloisi Pagina 3
Ricevimento Martedì 15.00 17.00 DIS, via Ariosto 25 Aula docenti adiacente aula A4 Si consiglia di inviare una email per conferma e di controllare la bacheca degli avvisi http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1011.html#avvisi 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 Operazioni sulle stringhe Pagina 5
I/O in C Il sistema di I/O del C è una interfaccia uniforme per il programmatore indipendentemente dal dispositivo di lettura e scrittura utilizzato. Scrivere o leggere da file o da video/tastiera non comporta differenze. 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 crea un livello di astrazione tra il programmatore e l oggetto (sia esso un file o dispositivo) Viene creato un meccanismo di astrazione tramite un flusso di dati o stream 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 vengono associati (con opportuni comandi) ai dispositivi fisici collegati al computer (tastiera, video, stampante, etc ) a file residenti sulla memoria di massa Pagina 10
Bufferizzazione Gli streams di I/O sono bufferizzati: questo significa che ogni volta viene letto da un file o scritto su di esso un "pezzo" di dimensioni stabilite attraverso alcune aree temporanee di immagazzinamento (è importante notare che il file puntatore punta effettivamente a questo buffer). Pagina 11
Bufferizzazione Questo metodo 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 ("\n" serve a questo). Qualsiasi uscita anormale del programma può causare problemi. 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 Produce una sequenza di caratteri che viene inviata allo stream stdout (video) Pagina 14
Esempio 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 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). Essi possono contenere caratteri alfanumerici codificati in formato standard (es. ASCII) direttamente leggibili dall utente (file di testo), oppure dati in un formato interpretabile dai programmi (file binari ). Pagina 16
Flusso sequenziale di byte terminato 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. L apertura e la chiusura dello stream associato al file non sono automatici come invece nel caso di stdin, stdout, stderr 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 che definiscono un comportamento differente nel sistema operativo (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 Cosa è <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 Per usare file esterni Si deve introdurre questo rappresentante interno del mondo esterno 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 *ingressodsc; FILE * si riferisce ad uno specifico tipo puntatore a file esterno ingressodsc è una variabile di tipo puntatore a file Attenzione: manca ancora 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 ed il file vero e proprio (esterno) <descrittore> = fopen( <nomefileesterno>, <modalità di uso> ); Esempio ingressodsc = fopen("filedaleggere.txt", "r"); Pagina 30
Modalità di uso Si deve specificare se il file va usato in lettura o 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 (void) { //altre dichiarazioni di variabili 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) { } 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 con delle informazioni ed una testina di lettura che è il descrittore. La testina viene spostata da istruzioni come fscanf e fprintf 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, come è chiamato sul disco, es. ingresso.dat <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 Contenuto del file di testo. esempio.txt Output Contenuto del file di testo. Pagina 42
Condizioni sull input Esiste già un file che deve essere aperto in lettura e analizzato per produrre il risultato desiderato. Pagina 43
Soluzione #include <stdio.h> int main (){ char ch; FILE *fd; //descrittore del file fd = fopen("esempio.txt", "r"); if(fd!= NULL){ while (fscanf(fd, "%c", &ch)!= EOF) { if(ch == ' ') printf("\n"); else printf("%c", ch); } } else printf ("\nerrore di apertura!"); fclose(fd); return 0; } 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 Da tastiera e video getchar (lettura) putchar (scrittura) Da 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 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"); else { 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 0; } 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 23 456.000000 12 8764.000000 90-78.000000 clienti.txt Pagina 50
Esercizio lettura da file Leggere dal file clienti.txt i seguenti dati: Numero 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"); else { 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 0; } Pagina 52
Esecuzione Conto Bilancio 23 456.000000 12 8764.000000 90-78.000000 Pagina 53