Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Scienze Matematiche Fisiche e Naturali
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Ernesto Burattini » 4.I file binari


Esempi d’uso di file binari


Esempi d’uso di file binari (segue)

Ci sono ancora due metodi che ci consentono di scrivere e leggere sui file binari.
I loro prototipi sono

write ( (char*) indirizzo-di-blocco-memoria, int grandezza-blocco)
read ( (char*) indirizzo-di-blocco-memoria, int grandezza-blocco)

Questi due metodi, abbastanza simili, gestiscono soltanto blocchi di memoria che, attraverso il casting, vengono trasformati in caratteri;
Il carattere * dopo il char, sta ad indicare che è necessario fornire soltanto l’indirizzo del primo carattere come primo parametro e la lunghezza di tutto il blocco come secondo parametro.

Esempi d’uso di file binari (segue)

Ad esempio per costruire un file di date, bisogna operare in questo modo:

  • definire un file di tipo fstream di nome fstream datafile;
  • aprire il file datafile sia in input che in output ed in formato binario: datafile.open(NomeFileFisico,ios::in|ios::out|ios::binary);
  • determinare la lunghezza del record Tpdata con l’istruzione sizeof: lunghezza=sizeof(Tpdata);
  • definire almeno una variabile di tipo Tpdata: Tpdata data1;
  • scrivere i dati posizionandosi nel punto voluto con l’istruzione seekp(……) e dare il comando: write( (char*) &data1, lunghezza);
  • leggere i dati posizionandosi nel punto voluto con l’istruzione seekg(……) dare il comando: read( (char*) &data1, lunghezza);

Se il file è di tipo ofstream si può utilizzare soltanto il metodo write(……………),
se è di tipo ifstream si può solo leggere con il metodo read(…………).

Esempio

Riprendiamo l’esempio della lezione 2.
In questo caso il programma deve gestire un insieme di persone conservando i dati sul disco; esso, inoltre, deve consentire l’inserimento dei dati, la ricerca di un dato conoscendo il cognome di una persona e la stampa su video di tutte le persone inserite o a scelta ordinate per data di nascita.
Le function

int MenuScelta();
void Inserimento(Tpersona&, char&);
void Stampa(const Tpersona&);

restano inalterate.
L’unica function a cui dovremo apportare delle modifiche è la function Ricerca.

Esempio (segue)

Altre modifiche riguarderanno il main:
dobbiamo introdurre la dichiarazione di un file binario ed una costante intera che rappresenti la lunghezza del record.

La prima volta che viene richiamato il programma, non trovando alcun file fisico, il programma va in errore; nella gestione dell’errore esso crea il file e, dopo, termina.
Tutte le esecuzioni successive non forniranno alcun errore di apertura del file.

La funzione Ricerca

La funzione, Ricerca, ricerca i dati di una persona. Il cognome inserito da tastiera viene inviato alla funzione che, attraverso una ricerca lineare, restituisce vero se la persona è stata trovata, falso nel caso in cui quel cognome non esiste nel file.

bool Ricerca(char cognome2[], fstream &file, Tpersona &s1, int Num, const int Lr)
{
int i=0;
file.seekg(0, ios::beg); //posiziona lettura testa file
bool trovato=false;
while
(i<Num && !trovato)    {
file.read((char*) &s1, Lr); //legge da file un singolo record
if (strcmp(s1.cognome,cognome2)==0) // confronta stringhe
{
trovato=true; }
else i++;
}
return trovato;
}

Procedura ordinaBubble

La procedura ordinaBubble ordina i dati che preventivamente sono stati inseriti in un array vet.

void ordinaBubble (Tpersona vet[], const int N)
{
int j, k;
Tpdata nasc1,nasc2;

for (k=0; k<N-1; k++)
for (j=N-2; j>=k; j--)
{ nasc1=vet[j].nascita;

nasc2=vet[j+1].nascita;
if ( dataNum(nasc1) > dataNum(nasc2) )
scambia (vet[j],vet[j+1]);
}
}

Esempio (segue)

void scambia (Tpersona &x1, Tpersona &x2)
{
Tpersona s;
s=x1;
x1=x2;
x2=s;
}

double dataNum(Tpdata x)
{
return x.anno*10000+x.mese*100+x.giorno;
}

Esempio (segue)

// PROTOTIPI

int MenuScelta();
void Inserimento(Tpersona&,char&);
void Stampa(const Tpersona&);
bool Ricerca(char[],fstream&, Tpersona&, int,const int);
double dataNum(Tpdata x);
void ordinaBubble(Tpersona [] , int n);
void scambia (double&, double&);

Il Main

Il main inizia con le dichiarazioni delle variabili:

persona1 di tipo Tpersona,
corrente, che rappresenta l’indice corrente dell’array,
NumPers, che rappresenta il numero attuale di persone memorizzate.
scelta denota l’operazione da eseguire volta per volta,
ch e cognome2 sono le variabili di input delle function Inserimento e Ricerca.

Il main contiene un ciclo do… while (il ciclo deve essere eseguito almeno una volta) al cui interno appare l’istruzione switch.

caso 1 corrisponde all’inserimento dati; se l’utente preme ’s’ i dati della persona vengono aggiunti all’array Persone e la variabile NumPers incrementata di uno;

caso 2 si assegna il cognome da ricercare e si richiama la funzione Ricerca: se il valore restituito di corrente è maggiore di -1, si stampano tutti i dati, altrimenti si avverte l’utente che il dato non è stato trovato;

caso 3 si esegue un ciclo for per stampare tutte le persone memorizzate.

caso 4 si esegue un ciclo for per stampare tutte le persone ordinate per data di nascita.

Funzione MenuScelta

La funzione MenuScelta deve scrivere sul monitor tutte le opzioni disponibili dando all’utente la possibilità di inserire soltanto un intero compreso tra 1 e 5. La funzione, dopo aver controllato che il valore rispetti tali limiti, deve restituirlo al programma chiamante.

int MenuScelta() {
int sc;
do {
cout <<" GESTIONE PERSONE "<< endl;
cout <<" \n";
cout <<"1 - INSERIMENTO"<
cout <<"2 - RICERCA"<
cout <<"3 - STAMPA TUTTI"<
cout <<"4 - STAMPA DATI ORDINATI x NASCITA"<
cout <<"5 - FINE"<
cout <<" Scelta="; cin >>sc;
} while (sc<1 || sc>5);
return sc;
}

Procedura Inserimento

La procedura Inserimento restituisce la struttura persona in pers1 e la variabile carattere ch che può contenere il carattere ’s’ o ‘n’. Le istruzioni della procedura si limitano ad acquisire i dati da tastiera.
void Inserimento (Tpersona& pers1, char& ch)
{
cout << " INSERIMENTO PERSONE "<
cout << "Cognome ="; cin >> pers1.cognome;
cout << "Nome ="; cin >>pers1.nome;
cout << "Data di nascita GG MM AAAA ="; cin >> pers1.nascita.giorno>>pers1.nascita.mese >>pers1.nascita.anno;
cout <<"Luogo di nascita:"; cin >>pers1.luogo;
cout<<"Salva (s/n)="; cin>>ch;
}

Procedura Stampa

La procedura Stampa visualizza sul monitor la struttura persona contenuta in pers1 con la clausola const; essa ha lo scopo di non consentire la variazione dei dati membri della struttura.

void Stampa(const Tpersona& pers1) {
cout << "Cognome :"<< pers1.cognome<< " Nome:"<
<
cout << "Luogo ="<<< " Data di nascita :";
cout<<<'/'<<<'/'<
cout<
}

Mostra codice

Esercizio 1

Sia dato un file non ordinato Azioni.dat di record del tipo:
struct tipor {
char azione[20];
float valore_minimo;
float valore_massimo;
float valori_ultima_settimana[7];
};

Costruire un array di record chiamato Affari contenente tutti i record riguardanti le azioni che hanno un valore medio, nell’ultima settimana, maggiore o uguale dei due terzi del valore_massimo.

Ordinare i record dell’array Affari per valore_massimo e, a parità, per nome azione.

Esercizio 2

Due file binari di nome “articoli.dat” e “acquisti.dat” rappresentano rispettivamente gli articoli e gli acquisti di una certa azienda. La struttura dei record è espressa in figura.

Fornire una procedura che scriva in un file binario “aggiorna.dat”, tutti gli articoli e, per ogni articolo, la quantità totale venduta, il costo medio e l’ultimo costo, aggiornando contemporaneamente anche il costo dell’articolo.


Esercizio 3

Sia dato un file di articoli di magazzino, articoli.dat, contenente record del tipo
struct TpArticolo {
int Codice;
char Descrizione[30];
int Quantità;
double Costo, Prezzo;
};

Scrivere una procedura che costruisca un array di record chiamato Guadagni che conservi tutti gli articoli il cui guadagno su ogni singolo pezzo è di almeno il 20%.
Tali articoli, ordinati per guadagno complessivo decrescente, devono essere scritti sul file guadagni.dat.

N.B. Guadagno complessivo = (Prezzo – costo)* Quantità.

Esercizio 4

Sia Utenti un array di record con la seguente struttura:

Struct tipor {
char nome[20], cognome[20], prodotto[20];
int venduto;
double totale;
};

Si suppone che l’array sia ordinato per prodotto;
Scrivere una procedura che registri su un file binario i record precedenti ordinati per cognome.

Esercizio 5

Consideriamo le strutture seguenti:

struct TpArt {
int Codice;
char Descrizione[30];
int Qmag: integer; //quantità contenuta in magazzino
float Prezzo;
int Scorta; //quantità minima in magazzino, oltre la quale si ordina altra merce
};
struct TpVend {
int Codice;
int Qvend;
};

Un grande magazzino ha degli articoli di tipo TpArt conservati nel file Articoli.bin; il campo Qmag rappresenta la quantità di quell’articolo presente in magazzino, Scorta la quantità minima necessaria per poter ordinare altri articoli dello stesso tipo.
Il file Vendite.bin contiene record del tipo TpVend che rappresentano la vendita giornaliera degli articoli; il campo Codice è lo stesso di TpArt, mentre Qvend rappresenta la quantità venduta. Entrambi i file sono ordinati per codice.
Scrivere una procedura che aggiorni il file Articoli.bin e stampi tutti gli articoli la cui quantità è minore uguale al campo Scorta.

Esercizio 6

Si considerino le definizioni mostrate a lato:

Una ditta acquista vari articoli dai fornitori contenuti nel file “fornitori.dat“. Il campo TotAcq rappresenta il totale in euro degli acquisti effettuati presso il fornitore nei primi tre trimestri dell’anno. Il file “fatture.dat” contiene, invece, le fatture di acquisto della ditta emesse durante tutto l’ultimo trimestre nei confronti degli stessi fornitori.
Calcolare per ogni fornitore il totale degli acquisti effettuati dalla ditta. Se la cifra supera i 100.000 euro, viene riconosciuto alla ditta un ulteriore sconto del 3% sul totale degli acquisti.

Scrivere una procedura che scriva su un file “sconto.dat

Nome fornitore, città, provincia, rimborso da richiedere

per tutti i fornitori della ditta, ordinati alfabeticamente per nome, a cui va richiesto lo sconto.


  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion