Lezione 8 - Dipartimento di Ingegneria dell`Informazione
Transcript
Lezione 8 - Dipartimento di Ingegneria dell`Informazione
Introduzione al C Stream e disk file Stream • Un canale è una sequenza di byte di dati • Sorgente o destinazione di dati che possono essere associati ad un disco o ad altre periferiche • Due tipi di stream: – Testo: sequenza di linee, di cui ciascuna può contenere da 0 a 255 caratteri e termina con \n (una linea non è una stringa, non termina con \0 !) – Binari:sequenza di byte non tradotti o interpretati in qualche modo particolare. Memorizzano qualsiasi tipo di dati tra cui anche testo. • File come flusso sequenziale di byte • Uno stream viene connesso ad un file o ad un dispositivo tramite un’operazione di apertura • La connessione è interrotta con un’operazione di chiusura • L’apertura di un file fornisce un puntatore ad un oggetto di tipo FILE • FILE contiene tutte le informazioni per la gestione dello stream • Quando un programma viene eseguito gli stream stdin, stdin, stdout, stdout, stderr sono già stati aperti stream predefiniti • stdin, stdin, stdout, stdout, stderr sono già stati aperti • Altri: stdprn (standard printer: LPT1) • stdaux (standard ausiliari: porta seriale COM1) • • • • Funzioni di STDIO.H: printf(), printf(),scanf (),scanf(), scanf(),puts (),puts(), puts(),gets (),gets(), gets(), getchar() getchar() perror() perror() (può richiedere STDLIB.H) Disk file stream • La differenza maggiore è che il programma deve esplicitamente connettere lo stream allo specifico disk file • Nomi di file: 8 caratteri, lettere a-z, numeri 0-9,_,!,$ char *filename = “c:\ c:\\data\ data\\list.txt” list.txt” • Se da tastiera un singolo \ Apertura di un file FILE *fopen( *fopen(const char *filename, *filename,const *mode) • FILE è un tipo definito in STDIO.H • Se fopen() fallisce ritorna NULL • Mode: – r : in lettura. Se il file non esiste, NULL – w : in scrittura. Se il file non esiste, lo crea. Se esiste, i dati esistenti vengono cancellati – a : appending. Se il file non esiste, viene restituito un errore. Se esiste, i nuovi dati seguono in coda gli esistenti – r+: r+ lettura e scrittura. Apre un file esistente in aggiornamento (sovrascrive) – w+: w+ scrittura e lettura. Se il file non esiste, lo crea. Se esiste sovrascrive – a+ :lettura e appending. Come a. Chiusura di file • int fclose(FILE fclose(FILE *fp); *fp); • Ritorna 0 se successo, -1 se fallisce • int fcloseall( fcloseall(void); void); • chiude tutti i file aperti e ritorna il numero di file chiusi (non definito nello standard ANSI) FILE *fp; *fp; char *filename = “c:\ c:\\data\ data\\list.txt” list.txt” if( if( (fp (fp = fopen( fopen(filename, filename,”r”) = = NULL) exit(1); … fclose( fclose(fp); fp); • aprifile.cpp • Il tipo di file di default è testo. Se si vuole aprire un file binario specificare il modo seguita da b. • Es. rb, ab…. Input/Output formattato • int fprintf(FILE fprintf(FILE *fp, *fp,char *fmt, *fmt,…); • Come printf, ma manda l’output allo stream specificato • int fscanf(FILE fscanf(FILE *fp, *fp,const char *fmt, *fmt,…); • Come scanf, ma manda l’input allo stream specificato Input/Output formattato • char *fgets( *fgets(char *str, *str,int n, FILE *fp); *fp); • legge una linea di input compreso \n fino ad un massimo di n caratteri del file; memorizza la linea letta in str terminandola con \0. Al termine del file o se si verifica un errore restituisce NULL. • int fputs( fputs(const char *str, *str, FILE *fp); *fp); Input/Output di caratteri • int getc(FILE getc(FILE *fp); *fp); • legge un carattere di input del file oppure EOF se incontra la fine del file; • int putc( putc(int c,FILE *fp); *fp); • scrive il carattere c sul file. Se ha successo restituisce il carattere scritto Funzioni di input/output diretto • Blocchi di dati sono scritti dalla memoria su disco • Blocchi di dati sono letti da disco nella memoria fread() fread() fwrite() fwrite() • int fwrite( fwrite(void *buf, *buf, int size, size, int count, count, FILE *fp); *fp); • Ritorna il numero di elementi scritti sul file con successo, un valore negativo se si è verificato un errore • buf è un puntatore alla regione di memoria nella quale sono memorizzati i dati da scrivere sul file • size è il numero di byte occupati da un singolo elemento • count è il numero di elementi da scrivere • int fread( fread(void *buf, *buf, int size, size, int count, count, FILE *fp); *fp); • Ritorna il numero di elementi letti dal file con successo (0 se il puntatore di lettura ha raggiunto lo fine del file) • buf è un puntatore alla regione di memoria nella quale saranno memorizzati i dati da leggere • size è il numero di byte occupati da un singolo elemento • count è il numero di elementi da scrivere • scrivileggi.cpp Accesso random • Si può accedere ad un file indicando la posizione a cui accedere • L’indicatore di posizione è misurato in byte dall’inizio del file • void rewind(FILE rewind(FILE *fp); *fp); • Riporta l’indicatore di posizione all’inizio del file (pos. 0) • long ftell(FILE ftell(FILE *fp); *fp); • Determina il valore dell’indicatore di posizione in byte dall’inizio del file. Se fallisce ritorna –1L • int fseek(FILE fseek(FILE *fp, *fp, long offset, int origine); • Permette un maggiore controllo dell’indicatore di posizione • offset: distanza dell’indicatore di posizione in byte da origine • origine: relativamente all’inizio • Ritorna 0 se l’indicatore viene mosso con successo, nonzero altrimenti • I valori dell’origine sono definiti tramite costanti simboliche definite in stdio.h • SEEK_SET: 0, muove l’indicatore di offset byte dall’inizio del file • SEEK_CUR: 1, muove l’indicatore di offset byte dalla posizione corrente • SEEK_END: 2, muove l’indicatore di offset byte dalla fine del file • Seekaccess.cpp Determinare la fine del file • Per file di testo: • int c; • While(( c=fgetc( (fp))!=EOF); While((c=fgetc ((c=fgetc fp))!=EOF); • Per file binari: • int feof feof(FILE (FILE *fp); *fp); • Ritorna 0, se non è stata raggiunta la fine del file, nonzero altrimenti • int remove( remove(const char *filename); *filename); • Il file da cancellare non deve essere aperto. Se il file esiste, viene cancellato e ritorna 0, altrimenti se fallisce ritorna nonzero • int rename( rename(const char *oldname, *oldname, const char *newname); *newname); • Se ha successo ritorna 0, se fallisce (ovvero oldname non esiste, esiste già un file chiamato newname, si cerca di rinominare un file in un disco diverso) ritorna nonzero Scrivere file di dati • Output formattato: – Scrivere dati formattati su un file – File di testo – File contenenti testo e numeri input di database o fogli elettronici • Output di caratteri: – scrivere caratteri o linee di caratteri – File di testo – File contenenti testo (non numeri) in un formato che può essere letto da programmi C o altri • Output diretto: – Salvare dati contenuti in memoria direttamente su file su disco – File binari – Input per programmi C Leggere file di dati • Il tipo di input da usare dipende dalla natura del file che deve essere letto Copiare un file • Non esiste una funzione di libreria, si devono compiere i seguenti passi: • Aprire il file origine in rb • Aprire il file destinazione in wb • Leggere un carattere alla volta dal file sorgente e copiarlo nel file destinazione finchè non viene raggiunta la fine del file sorgente Esercizio • Un file di testo in memoria secondaria contiene le informazioni relative alle verbalizzazioni di un esame nella seguente forma: (rossi 27) (verdi 29) (bianchi 25) • ovvero il file contiene delle coppie cognome-voto tra parentesi tonde separate da spazi o newline. • Scrivere una funzione C che riceve come parametro il nome del file e stampa la media dei voti ottenuti dagli studenti e il cognome e voto dello studente con il voto più alto. Se più studenti hanno ottenuto lo stesso voto massimo, la funzione restituisce il primo. Generazione di numeri casuali?? #include<stdlib.h> i=rand(); // 0<= i<=216 (intero di due byte) i=rand() % j ………PSEUDOCASUALI: ad ogni esecuzione si rigenerano gli stessi numeri #include<stdlib.h> unsigned seed; srand(seed); srand(time(NULL)); i=rand(); // seme inserito dall’utente // seme calcolato in automatico a seconda dell’ora segnata dall’orologio interno ( randomize() )