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