Corso di Laurea in Ingegneria Meccanica A-K Fondamenti di Informatica A. A. 2011-2012 1
Memorizzazione dei dati su dispositivi di memoria esterna Dispositivi di memorizzazione secondaria sono: dischi, CDROM, i DVD, le pendrive USB Vantaggi - Possibilità di memorizzare grandi quantità di dati - Memorizzazione dei dati in maniera permanente Modalità di memorizzazione - Dati organizzati in File File: ARCHIVIO contenente informazioni memorizzate in un formato opportuno 2
Operazioni di input/output Le operazioni di input/output viste fino ad ora: la tastiera come dispositivo di input lo schermo come dispositivo di output Il linguaggio C gestisce le operazioni su file esattamente nello stesso modo(come operazioni su di un dispositivo di input o output). 3
Stream In C le operazioni di I/O vengono semplificate attraverso l'uso degli stream. Gli stream sono delle astrazioni rappresentative di un file o di un dispositivo fisico, che vengono manipolate attraverso l'uso di puntatori. Flusso di comunicazione tra il file system e il dispositivo 4
Lo stream è bufferizzato: viene riservato un buffer per evitare ritardi o interruzioni nella fase di lettura e scrittura. Buffer :memoria temporanea o intermediaria di transito. Zona di memoria utilizzata temporaneamente per l input e output dei dati. 5
Lo stream è bufferizzato: viene riservato un buffer per evitare ritardi o interruzioni nella fase di lettura e scrittura. Buffer :memoria temporanea o intermediaria di transito. Zona di memoria utilizzata temporaneamente per l input e output dei dati. Questo metodo rende efficiente l'i/o ma i dati scritti in un buffer non compaiono nel file finché il buffer non e' riempito o scaricato ("\n" serve a questo). Qualsiasi uscita anormale del programma può causare problemi. 6
Funzione di apertura del file La prima cosa da fare è aprire un file; per fare ciò si usa la funzione fopen: FILE *fopen(nome_file, modalità_di_apertura); nome_file e il nome del file che si intende aprire; intero percorso che individua il file nel sistema operativo. modalità_di_apertura indica la modalità in cui di intente aprire il file Questa funzione restituisce un puntatore ad un oggetto di tipo file, se il flusso di comunicazione viene aperto con successo. Restituisce NULL in caso contrario. 7
Modalità di Apertura del File "r" apre un file in lettura, il file deve già esistere e non è modificabile. "w" crea un file per la scrittura, se il file esiste già, ne elimina il contenuto e il puntatore si posiziona all inizio del file. "a" apre o crea un file per scrivere in fondo dello stesso (append), se esiste già non distrugge il contenuto e si posiziona in coda ciò che già scritto, se non esiste lo crea. "r+" apre un file in aggiornamento (lettura e scrittura) le operazioni saranno eseguite all inizio del file(file esistente). "a+" apre o crea un file per lettura e scrittura, le operazioni saranno eseguite alla fine del file. w+" crea un file per la scrittura che potrà essere consultato anche in lettura, se il file esiste già, ne sovrascrive il contenuto. 8
Tipi di File Posso aprire un flusso di comunicazione di due tipi: 1. Binario:flusso di comunicazione di byte, il sistema operativo non fa nessuna assunzione sul contenuto del testo, trasferisce solo byte. 2. Testo:Il sistema operativo converte i byte che hanno un significato particolare prima di porli nel buffer (es : NewLine, Tab ). t b text mode binary mode 9
Gli stream, qualunque uso ne sia stato fatto,devono essere prima "puliti" e poi chiusi, con le funzioni fflush e fclose: fflush(file *); fclose(file *); chiude il flusso di comunicazione. Per poter operare correttamente è necessario includere l'header file <stdio.h> che contiene tutte funzioni per l'input/output, comprese quelle che operano sui file. 10
Esempio #include <stdio.h> main() {File *testo; testo=fopen( Primo_File.txt, w+t ); fclose(testo); 11
Esempio #include <stdio.h> main() {File *testo; Dichiaro un puntatore ad una struttura di tipo file. File deve essere dichiarato da qualche parte in questo caso in stdio testo=fopen( Primo_File.txt, w+t ); fclose(testo); 12
Esempio #include <stdio.h> main() {File *testo; Dichiaro un puntatore ad una struttura di tipo file. File deve essere dichiarato da qualche parte in questo caso in stdio testo=fopen( Primo_File.txt, w+t ); fclose(testo); Restituisce un puntatore e gli associo quello che ho precedentemente dichiarato 13
Esempio #include <stdio.h> main() {File *testo; Dichiaro un puntatore ad una struttura di tipo file. File deve essere dichiarato da qualche parte in questo caso in stdio testo=fopen( Primo_File.txt, w+t ); fclose(testo); Da questo momento non avrò più riferimenti al nome del file ma uso come unico riferimento il puntatore al file. 14
Controllo apertura #include <stdio.h> #include<stdlib.h> main() {File *testo; if(testo=fopen( Primo_File.txt, r+t )==NULL) {printf( Impossibile aprire il file\n ); exit(1); fclose(testo); 15
Controllo apertura #include <stdio.h> #include<stdlib.h> main() {File *testo; if(testo=fopen( Primo_File.txt, r+t )==NULL) {printf( Impossibile aprire il file\n ); exit(1); exit(1) mi permette di uscire dal programma 1 indica che l uscita è dovuta ad un errore; in questo caso il fatto che il file non esiste fclose(testo); 16
#include <stdio.h> #include<stdlib.h> main() {File *bin; if(bin=fopen( file.dat, w+b )==NULL) {printf( Impossibile aprire il file\n ); exit(1); fclose(bin); 17
Lettura e Scrittura a blocchi su file fread(); legge una sequenza di byte fwrite(); scrive una sequenza di byte Essendo sequenze di byte, non sono interpretate, quindi posso rappresentare qualunque informazione(testi, numeri, immagini ) 18
fwrite (void*,long,int,file*); void*: indirizzo di memoria della variabile che conserva i dati da scrivere sul file long:indica la dimensione del singolo elemento (byte)da scrivere int:indica il numero di elementi da scrivere per volta(scrive int elementi di dimensione long) File*:indica il file su cui andare a scrivere Restituisce un intero che rappresenta il numero di elementi realmente scritti. 19
fread (void*,long,int,file*); void*: indirizzo di memoria della variabile che riceve i dati letti dal file long: indica la dimensione del singolo elemento (byte)da leggere int: indica il numero di elementi da leggere per volta(scrive int elementi di dimensione long) File*: indica il file da cui andare a leggere Restituisce un intero che rappresenta il numero di elementi realmente letti(lo usiamo per controllare se il file è terminato). 20
Esempio 1 Salvare su un file binario già esistente numeri.dat il contenuto di un array di 10 interi #include <stdio.h> #include<stdlib.h> main() { File *bin; Int vett[10]={1,3,5,7,9,2,4,6,8,10; if(bin=fopen( numeri.dat, r+b )==NULL) {printf( Impossibile aprire il file\n ); exit(1); fwrite(vett,sizeof(int),10,bin); fclose(bin); 21
Esempio 1 Salvare su un file binario già esistente numeri.dat il contenuto di un array di 10 interi #include <stdio.h> #include<stdlib.h> main() { File *bin; Int vett[10]={1,3,5,7,9,2,4,6,8,10; if(bin=fopen( numeri.dat, r+b )==NULL) {printf( Impossibile aprire il file\n ); exit(1); sizeof () restituisce la dimensione del dato che stiamo scrivendo (num di byte),anche se in questo fwrite(vett,sizeof(int),10,bin); caso è un int la sua dimensione non è fissa fclose(bin); 22
Esempio2 Leggere da un file binario esistente una sequenza di interi scrivendoli in un array #include <stdio.h> #include<stdlib.h> main() { File *bin; int vett[40],i,n; if(bin=fopen( numeri.dat, r+b )==NULL) {printf( Impossibile aprire il file\n ); exit(1); n=fread(vett,sizeof(int),40,bin); for(i=0;i<n;i++) printf( %d,vett[i]); fclose(bin); 23
Esempio2 Leggere da un file binario esistente una sequenza di interi scrivendoli in un array #include <stdio.h> #include<stdlib.h> main() { File *bin; int vett[40],i,n; fread() tenta di leggere 40 interi, se il file termina prima ne legge meno; n ci dice quanti realmente ne ha letti if(bin=fopen( numeri.dat, r+b )==NULL) {printf( Impossibile aprire il file\n ); exit(1); n=fread(vett,sizeof(int),40,bin); for(i=0;i<n;i++) printf( %d,vett[i]); fclose(bin); 24
Esempio3 #include<stdio.h> #include<stdlib.h> main() { FILE *bin; int dato=5; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fclose(bin); 25
Esempio3 #include<stdio.h> #include<stdlib.h> main() { FILE *bin; int dato=5; int prova; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fclose(bin); 26
Esempio3 #include<stdio.h> #include<stdlib.h> main() { FILE *bin; int dato=5; int prova; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fread(&prova,sizeof(prova),1,bin); printf("%d\n", prova); fclose(bin); 27
Posizionamento su file 1/2 fseek(file*,long,int) File* identifica il file in cui sto lavorando long indica lo scostamento da un riferimento (numero di byte) int rappresenta il riferimento, indica il punto rispetto al quale calcolo lo scostamento Esisteno 3 possibili riferimenti SEEK_SET: inizio del file SEEK_END: fine del file SEEK_CUR: posizione corrente Restituisce 0 quando viene eseguita con successo un intero in caso contrario fseek(bin,0,seek_set) fseek(bin,0,seek_end) 28
Posizionamento su file 2/2 ftell(file*); Restituisce la posizione corrente all interno del file assocciato al puntatore che lo identifica e -1 in caso di errore. rewind(file*); Riavvolge il file e vi si posiziona all inizio,il funzionamento è simile a: fseek(bin,0,seek_set) ; ma rewind() non restituisce alcun valore 29
Esempio3.1 #include<stdio.h> #include<stdlib.h> main() { File *bin; int dato=5; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fclose(bin); 30
Esempio3.1 #include<stdio.h> #include<stdlib.h> main() { File *bin; int dato=5; int prova; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fclose(bin); 31
Esempio3.1 #include<stdio.h> #include<stdlib.h> main() { File *bin; int dato=5; int prova; if ((bin=fopen("numeri.dat","r+b"))==null) if((bin=fopen("numeri.dat","w+b"))==null) {printf("impossibile aprire il file\n"); exit(1); fwrite(&dato,sizeof(dato),1,bin); fseek(bin,-sizeof(dato),seek_cur) ; fread(&prova,sizeof(prova),1,bin); printf("%d\n", prova); fclose(bin); 32
Esempio4 #include<stdio.h> #include<stdlib.h> main() { File *fp; int anno; struct Dati {char nome[40], cognome[40]; int annonascita; ; struct Dati Persona; if(fp=fopen( file.dat, r+b )==NULL) //leggiamo informazioni da un file esistente {printf( Impossibile aprire il file\n ); exit(1); fseek(fp,0,seek_set); printf( inserire anno di nascita da cercare ); //anno da cercare scanf( %d,&anno); while(fread(&persona,sizeof(persona),1,fp)==1); If(anno==Persona.annoNascita). fclose(bin); 33
Cancellare e Rinominare un File rename(vecchio_nome,nuovo_nome); Restituisce 0 se l operazione è avvenuta con successo, un intero in caso contrario. remove(nome_file); NB:non si può eliminare un file aperto 34
Operazioni di lettura e scrittura formattata su file 35
Lettura da file fscanf(file *nome_puntatore, stringa di controllo, indirizzo elementi); Permette di effettuare l input di informazioni da file secondo un formato specificato Restituisce: EOF nel caso di raggiungimento della fine del file o nel caso si verifichi un qualsiasi errore Il numero di elementi letti dal file nel caso non si siano verificati errori 36
Stringa di controllo 37
Lettura da file Es Contenuto del file : Nome 1 Cognome 1 Codice 1 Nome 2 Cognome 2 Codice 2 Nome 3 Cognome 3 Codice 3.. La lettura di questo file (già aperto) identificato dalla variabile puntatore fp puo essere effettuata nel modo seguente Char nome[ ],cognome[ ],codice[ ]; while(fscaf(fp, %s %s %s,nome,cognome,codice)!=eof) { Esegui le operazioni 38
Scrittura su file fprintf(file *nome_puntatore, stringa di controllo, indirizzo elementi); consente di scrivere gli elementi di cui è specificato il formato, sul file indicato dall utente tramite il puntatore Restituisce: EOF nel caso si verifichi un qualsiasi errore il numero di elementi scritti sul file nel caso l operazione si sia conclusa con successo 39
Lettura di caratteri da file int fgetc (FILE*nome_puntatore); La funzione fgetc legge dal file individuato dal nome del puntatore, il successivo carattere restituendo: Il valore (convertito in intero) del codice ASCII del carattere EOF se è stata raggiunta la fine del file 40
Lettura di caratteri da file Es: Per leggere dall inizio alla fine un file di testo (già aperto )individuato da fp, si puo utilizzare il codice seguente: char c; c=fgetc(fp); while(c!=eof) { esegui le operazioni c=fgetc(fp); 41
Scrittura di caratteri su file int fputc(variabile_char, FILE*nome_puntatore); La funzione fputc interpreta variabile_char come il codice ASCII di un carattere, lo scrive sul file individuato dal puntatore e restituisce: Il codice ASCII del carattere stesso se l operazione ha avuto successo EOF in caso di errore 42
Lettura di linee da file char* fgets (char*stringa,int lunghezza,file*nome_puntatore); La funzione legge una riga dal file individuato dal nome del puntatore fino al raggiungimento di un carattere di fine stringa o fino alla lettura di lunghezza-1 caratteri Restituisce: il puntatore alla stringa se l operazione ha avuto successo(la riga è stata memorizzata con successo nella variabile stringa) NULL se si è arrivati alla fine del file o si è verificato un errore 43
Scrittura di linee su file int fputs (char*stringa,file*nome_puntatore); La funzione fputs scrive la linea stringa sul file individuato dal nome del puntatore e restituisce: Un intero in caso di operazione andata a buon fine EOF in caso di errore 44
Funzioni di supporto Restituisce: int feof (FILE*nome_puntatore); il valore diverso da zero(vero) quando viene raggiunta la fine del file Il valore zero(falso) in tutti gli altri casi while(!feof(fp)) {esegui le operazioni. 45
Funzioni di supporto int ferror(file*nome_puntatore); Restituisce: il valore logico vero in caso di errore Il valore logico falso in caso contrario 46
Esempio 1/2 #include<stdio.h> #include<stdlib.h> main() { File *fp_in,*fp_out; //file input lettura, file output scrittura int nc; char c; if(fp_in=fopen( testo.txt, rt )==NULL) {printf( Impossibile aprire il file\n ); exit(1); //file esistente if(fp_out=fopen( contanumeri.txt, wt )==NULL) {printf( Impossibile aprire il file\n ); exit(1); 47
Esempio 2/2 nc=0; While(!feof(fp_in)) {fscanf(fp_in; %c,&c); If(c=> 0 && c<= 9 ) {nc++; fprintf(fp_out, %c,&c); printf( nel file testo.txt sono presenti %d numeri compresi tra 0 e 9,nc); fflush(fp_in); fclose(fp_in); fflush(fp_out); fclose(fp_out); 48