18
File ad accesso Random
• Random access files
– Per accedere direttamente singoli record senza ‘attraversare’ quelli che lo precedono – I dati possono essere inseriti senza distruggere gli altri
– I dati registrati possono essere modificati senza sovrascrivere o cancellare parzialmente quelli esistenti.
– un file sequenziale deve essere riscritto completamente se si vuole modificare qualche informazione in un record
• Tipicamente i record registrati in un file random hanno tutti la stessa lunghezza (in byte)
… analizzeremo solo questo caso …
0 200 300 400 500
byte offsets
}
} } } } } }
100
100 bytes
100 bytes
100 bytes
100 bytes
100 bytes
100 bytes
Random Access File
– Sono file ‘binari’
• Tutti i dati dello stesso tipo hanno una stessa dimensione in memoria
• Tutti i record dello stesso tipo hanno la stessa lunghezza
• Essendo file binari, i dati registrati non sono adatti per la lettura umana
– I dati non sono formattati e registrati come "raw bytes"
20
Random Access File
• Operazioni di apertura e chiusura file nel linguaggio C:
… come per i file sequenziali …
Apertura file :
< nome_puntatore_file > = fopen (“<nomefile>”, <modo_apertura>);
Chiusura file:
fclose(< nome_puntatore_file >);
Random Access File
• Operazioni di apertura e chiusura file:
modi di apertura:
• “w” crea un file per scrivere in esso di valori; se il file già esiste esso sarà riscritto cancellando il contenuto precedente
• “r” apre il file in lettura per leggerne il contenuto
• “a” apre il file per scrivere altri valori alla fine dello stesso
• “w+” crea un file per l’aggiornamento (lettura e scrittura) ; se il file già esiste esso sarà riscritto cancellando il contenuto precedente
• “r+” apre il file in aggiornamento (lettura e scrittura)
• “a+” apre il file per l’accodamento, la scrittura sarà eseguita alla fine del file
22
Random Access File
• Operazioni di scrittura e lettura:
– fwrite – per scrivere un record su un file random – fread – per leggere il contenuto di un file random
Sintassi:
• fwrite( &var_name, sizeof( <type> ), 1, myPtr );
• &var_name – nome della variabile da scrivere sul file (ovvero locazione di memoria da cui trasferire i bytes nel file)
• sizeof( <type> ) – dimensione in bytes di var_name in base al suo tipo (ovvero numero di bytes da trasferire nel file)
• 1 – nel caso di array numero degli elementi dello array da scrivere nel file (in questo caso un solo elemento). E’ possibile scrivere, in una sola volta, più elementi di un array indicandone il numero nel terzo argomento
• myPtr – puntatore al file
• fread … sintassi simile
Random Access File
• Per scrivere structs (cioè records)
• fwrite( &myObject, sizeof (<struct myStruct>), 1, myPtr );
– &myObject nome della variabile di tipo struct myStruct da scrivere nel file – sizeof Restituisce la dimensione in bytes dell’elemento indicato tra le parentesi
(lunghezza del record in bytes) – 1 è scritto un solo record per volta – myPtr puntatore al file
24
• fread
– Legge uno specificato numero di bytes da un file random
fread(&myObject, sizeof (<struct myStruct>), 1, myPtr);
– Gli argomenti hanno lo stesso significato del caso fwrite(…)
• fseek
– Per posizionarsi all’interno del file ad uno specifico record – fseek( myPtr, offset, symbolic_constant);
• myPtr – puntatore al file
• offset – indicatore delle posizione nel file (0 è la prima posizione)
• symbolic_constant – specifica la posizione di lettura nel file
• SEEK_SET – lo offset è calcolato dall’inizio del file
• SEEK_CUR - lo offset è calcolato a partire dalla posizione corrente
• SEEK_END - lo offset è calcolato a partire dalla fine del file
26
#include <stdio.h>
main()
{ struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
int i;
struct studente studenteSannio_vuoto = { 0, " ", " ", 0.0 };
FILE *cfPtr;
cfPtr = fopen("studenti.dat", "w" );
if ( cfPtr == NULL )
printf("Non possibile aprire il file !!.\n" );
else
{for( i = 1; i <= 100; i++ ) // scrive 100 record ‘vuoti’ nel file {studenteSannio_vuoto.matricola=i;
fwrite( &studenteSannio_vuoto,sizeof( struct studente),1,cfPtr );
}
fclose( cfPtr );
}
printf("FINE PROGRAMMA");
}
Random Access File
Programma esempio Creazione di un file random inizializzandolo in modo sequenziale
#include <stdio.h>
main() {
struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
FILE *cfPtr;
struct studente studenteSannio;
int offst;
if ((cfPtr = fopen("studenti.dat", "r+")) == NULL) /* Scrive record in un file random già
inizializzato con record vuoti*/
Random Access File
Programma esempio
Scrittura random di record nel file
while (studenteSannio.matricola != 0) { printf(“Cognome:\n? ");
scanf(“\n%s", &studenteSannio.cognome);
printf(“Nome:\n? ");
scanf(“\n%s", &studenteSannio.nome);
printf(“Media Voti:\n? ");
scanf(“\n%f", & studenteSannio.media_voti);
offst = (studenteSannio.matricola - 1) * (sizeof(struct studente));
fseek(cfPtr, offst, SEEK_SET); //si posiziona per la scrittura fwrite(&studenteSannio, sizeof(struct studente), 1, cfPtr);
printf("Immetti la matricola (da 1 a 100, 0 per terminare)\n");
scanf("%d", & studenteSannio.matricola);
} }
fclose(cfPtr);
printf("FINE PROGRAMMA\n");
}
/* Legge e stampa record da un file random */
#include <stdio.h>
main()
{ struct studente{
int matricola;
char cognome[15];
char nome[10];
float media_voti;
};
FILE *cfPtr;
struct studente studenteSannio;
if ((cfPtr = fopen(“studenti.dat", "r")) == NULL) printf(“Apertura file non possibile !!!\n");
else
{printf("%-6s%-16s%-11s%10s\n", “Matr.", “Cognome“, “Nome", “Media");
while (!feof(cfPtr))
{fread(&studenteSannio, sizeof(struct studente), 1, cfPtr);
if (!feof(cfPtr))
if (studenteSannio.media_voti != 0)
printf("%-6d%-16s%-11s%10.2f\n", studenteSannio.matricola,
studenteSannio.cognome, studenteSannio.nome,studenteSannio.media_voti);
} }
fclose(cfPtr);
printf(“FINE PROGRAMMA\n");
}
Random Access File
Programma esempio Lettura dei record nel file
/* modifica record in un file random */
………
printf("\n\n Vuoi immettere/modificare altri studenti ? 1= SI\n");
scanf("%d", &risp);
while (risp==1)
{printf("Immetti la matricola (1 to 100, 0 per terminare)\n? ");
scanf("%d", &studenteSannio.matricola);
printf("Cognome:\n? ");
scanf("\n%s", &studenteSannio.cognome);
printf("Nome:\n? ");
scanf("\n%s", &studenteSannio.nome);
printf("Media Voti:\n? ");
scanf("\n%f", &studenteSannio.media_voti);
offst = (studenteSannio.matricola - 1) * (sizeof(struct studente));
fseek(cfPtr, offst, SEEK_SET);
fwrite(&studenteSannio, sizeof(struct studente), 1, cfPtr);
printf("\n\n Vuoi immettere/modificare altri studenti ? 1= SI\n");
scanf("%d", &risp);
}
fclose(cfPtr);
printf("FINE PROGRAMMA\n");
system("pause");
}
Programma esempio Modifica dei record nel file
Definizione del problema:
Sviluppare un programma che dato in input un numero di matricola (compreso tra 1 e 100) permette di accedere, nel file studenti.dat degli esempi precedenti, direttamente alla posizione corrispondente al valore di matricola immessa e di far visualizzare a video le restanti informazioni registrate nel file per quella matricola, o un messaggio di errore se quella matricola non esiste nel file,Definizione della specifica del programma:
LO STUDENTE COMPLETI E SCRIVA IL PROGRAMMA CON LA RELATIVA DOCUMENTAZIONE
Esercizio con File accesso random
32
Definizione del problema:
Si vogliono memorizzare su un file ad accesso random il numero di matricola, il cognome, il nome, l’indirizzo di e-mail ed il numero di telefono degli studenti del corso di elementi di informatica; si vogliono poi visualizzare tutte leinformazioni registrate ed eventualmente aggiungerne altre o ricercare, aggiornare o cancellare un elemento in base al numero di matricola o all’indirizzo di e-mail.
Definizione della specifica del programma:
LO STUDENTE COMPLETI E SCRIVA IL PROGRAMMA CON LA RELATIVA DOCUMENTAZIONE