PDA

Visualizza la versione completa : C++ Strutture e file binari


Vlizer
02-06-2014, 15:55
Salve a tutti,
premetto che non sono per nulla esperto di programmazione in c++. Sono uno studente e sto avendo molta difficoltà con questo mini progetto.
L'obbiettivo è creare delle strutture che vengano salvate anche su dei file binari ( è un programma tipo per un ospedale e avro un file per i pazienti ed uno per gli esami) in modo tale che quando riaprirò il programma posso riprendere i dati.

A me è venuto in mente di organizzarlo così

questa è la mia struttura


struct recPazienti {
int codPaz;
char cognomePaz[30];
char nomePaz[30];
char dataNascita[15];
int telefonoPaz;
};

Dal menu principale con una voce mando una funzione che carica struttura. Ecco a funzione :


void nuovoPaziente (recPazienti paziente[],int &i){

int cont;
system("CLS");
cout<<"\n Quanti pazienti vuoi inserire ?";
cin>>cont;
cout<<"\n Inserisci i dati richiesti";
do {
cout<<"\n\n Codice del paziente : ";
cin>>paziente[i].codPaz;
cout<<" Cognome : ";
cin>>paziente[i].cognomePaz;
cout<<" Nome : ";
cin>>paziente[i].nomePaz;
cout<<" Data di nascita : ";
cin>>paziente[i].dataNascita;
cout<<" Numero di telefono : ";
cin>>paziente[i].telefonoPaz;
cout<<"\n~~~~~~~~~~~~~~~~~~~~~~~~~~";
fflush(stdin);
i++;
cont--;
scriviFilePaziente(paziente);
} while(cont!=0);
}

Poi come vedete appena carico un paziente lo metto subito anche su file con questa funzione :



void scriviFilePaziente(recPazienti paziente[]){
pPaz=fopen("Pazienti.dat","ab");
if (pPaz==NULL){
printf("ERRORE : File Pazienti.dat non aperto");
return;
}
fwrite(&paziente, sizeof(recPazienti),1,pPaz);
fclose(pPaz);
}

e fino a qui ok. Dopo con un altra voce del menu' principale chiamo due funzioni
Una che mette i dati dal file alla struttura :


void caricaStrPaz(recPazienti paziente[], int &i){
int n;
pPaz=fopen("Pazienti.dat","rb");
if (pPaz==NULL){
printf("Il file Pazienti.dat non esiste");
}
while(!feof(pPaz)){
n = fread(&paziente[i], sizeof(recPazienti),1,pPaz);
if (n==1){
i++;
}
}
fclose(pPaz);
}

e l'altra funzione che alla fine mi visualizza la struttura


void visualPaz(recPazienti paziente[], int num){
int i;
system("CLS");
cout<<"\n Elenco dei dati di tutti i pazienti "<<endl;
for (i=0;i<num;i++){
cout<<"\n Codice del paziente : "<<paziente[i].codPaz;
cout<<"\n Cognome : "<<paziente[i].cognomePaz;
cout<<"\n Nome : "<<paziente[i].nomePaz;
cout<<"\n Data di nascita : "<<paziente[i].dataNascita;
cout<<"\n Numero di telefono : "<<paziente[i].telefonoPaz;
cout<<"\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
}
cout<<"\n Premere un tasto per tornare al menu' principale...";
getch();
}

nel main oltre al menu switch ho questo :


ecPazienti paziente[DIM]; (dim lo definito a 1000)
int posPaz=0,posEsa=0;

e queste sono le chiamate delle funzioni sopra riportate :


nuovoPaziente(paziente,posPaz);
caricaStrPaz(paziente,posPaz);
visualPaz(paziente,posPaz);

Il programma non funziona per nulla. Non visualizza niente di quello che deve ma solo caratteri strani al posto dei dati.
Se qualcuno ha la pazienza di aiutarmi gliene sarei grato. Sto impazzendo ed è un lavoro molto importante.

return
02-06-2014, 16:03
Credo il problema ci sia perchè il software cerca di aprire il file "Pazienti.dat", ma il software non ha nessuna conversione per aprire i file .dat e quindi li apre come normali file di testo e di conseguenza ti fa visualizzare caratteri strani.

Vlizer
02-06-2014, 16:13
Ciao,
sai come posso risolvere ? Uso dev c++

oregon
02-06-2014, 16:14
Tanto per cominciare non usare la feof per un file binario. Individua la sua lunghezza, dividila per la lunghezza di una singola struttura e imposta un ciclo for per leggere i dati.

@return ... non ho capito quello che scrivi ... il programma apre il file in binario e non ha alcun bisogno di convertire nulla ...

Vlizer
02-06-2014, 16:17
ciao oregon.
come devo modificare la funzione per fare come mi hai consigliato ?
scusa la domanda ma non sono molto esperto

oregon
02-06-2014, 16:25
1) Ottieni la grandezza del file binario con le funzioni fseek/ftell ( http://www.cplusplus.com/reference/cstdio/ftell/ )

2) Dividi la grandezza così ottenuta per la grandezza del record ( grandezza/sizeof(struct RecPazienti) )

3) Il risultato della divisione è il numero di record da leggere a partire dall'inizio del file con una for ...

Vlizer
02-06-2014, 16:39
Ho modificato la funzione eccola :


void caricaStrPaz(recPazienti paziente[], int &i){

int n,j,size,numRec;
pPaz=fopen("Pazienti.dat","rb");

if (pPaz==NULL){
printf("Il file Pazienti.dat non esiste");
}

fseek (pPaz, 0, SEEK_END);
size=ftell (pPaz);

numRec=size/sizeof(struct recPazienti);

for(j=0;j<numRec;j++){

n = fread(&paziente[i], sizeof(recPazienti),1,pPaz);

if (n==1){
i++;
}
}
fclose(pPaz);

}

Ora però quando avvio questa e dopo la visualizzazione della struttura non visualizza nulla.

oregon
02-06-2014, 17:22
Vedo che chiami

caricaStrPaz(paziente,posPaz);

ma il secondo parametro deve essere un puntatore ... no?

Vlizer
02-06-2014, 17:28
Mi sto confondendendo ora.

In effetti avevo messo così perchè caricava la tabella da 0 in poi e in base a dove arrivava usavo quel valore per visualizzare la struttura.

Cosa devo mettere ?

oregon
02-06-2014, 17:48
Va bene così ... è passato per riferimento ... dovrei provare tutto il codice quando ho un momento libero ...

Loading