View Full Version : File in c++
Gogeta ss4
22-09-2004, 16:15
void lettura(rubrica indice)
{
FILE *fp;
fp=fopen("rubrica.txt","r");
if(fp!=NULL)
{
while(!feof(fp))
{
fread(&indice,sizeof(indice),1,fp);
cout <<"\nNome: " <<indice.nome;
cout <<"\nCognome: " <<indice.cognome;
cout <<"\nIndirizzo: " <<indice.indirizzo;
cout <<"\nNumero: " <<indice.numero;
}
}
else
cout <<"\nFile inesistente";
fclose(fp);
}
Ho un problema con tutta la lettura del file, nel file ho una sola struttura e non so perchè il ciclo di lettura me lo fa due volte visualizzandomi 2 volte la struttura, dove sbaglio??
AnonimoVeneziano
22-09-2004, 18:14
Perchè non raggiungi l'EOF subito , ma al ciclo dopo .
in pratica tu nel file hai questi dati :
DATO1 DATO2 DATO3 DATO4 EOF
DATO1 è il nome
DATO2 è il cognome
e così via .
tu dici a fread di leggere la struttura, che è composta da quei 4 dati , ma fread non raggiunge in realtà EOF , ma si ferma a DATO4 , che è l'ultimo elemento della struttura .
Così al successivo controllo della struttura iterativa "while" il sistema si renderà conto che la fine del file non è ancora stata raggiunta, e continuerà il Ciclo .
Ovviamente ormai non c'è + niente da leggere, ma nonostante questo riesegue tutte le operazioni da capo cercando di caricare la struttura di nuovo .
Quello che ti consiglio di fare è di implementare un sistema per il controllo dei dati letti. FREAD dà come valore di ritorno il numero di elementi che è riuscita a leggere con successo .
potresti memorizzare questo valore in una variabile , e controllarla con una "if" prima di mandare in output "Nome" "Cognome" ...
Dato che la struttura è di dimensione fissata puoi fare in modo di controllare se il valore mandato in output da "fread" sia 0 .
Se il valore mandato in output da fread è 0 significa che non è riuscita a leggere COMPLETAMENTE nessuna struttura dal file durante questa chiamata e quindi puoi sfruttare questo fatto per far saltare alla tua funzione la scrittura a schermo di tutte quelle cose che non servono .
Magari quello che ho scritto può sembrare un po' oscuro , ma ti consiglio di dare bene un occhiata al prototipo di funzione di FREAD per informazioni chiarificatorie sul suo funzionamento . Se stai su un sistema UNIX "man fread" basta per avere informazioni sulla stessa .
Ciao :)
Gogeta ss4
22-09-2004, 19:22
infatti ho fatto così, grazie :D
/\/\@®¢Ø
22-09-2004, 20:53
Originariamente inviato da Gogeta ss4
Ho un problema con tutta la lettura del file, nel file ho una sola struttura e non so perchè il ciclo di lettura me lo fa due volte visualizzandomi 2 volte la struttura, dove sbaglio??
Visto che parli di C++, la cosa piu' semplice e' forse quella di ricorrere alle eccezioni per gestire la fine del file:
#include <fstream>
using namespace std;
void lettura(rubrica indice)
{
ifstream f("rubrica.txt" );
f.exceptions( ios_base::eofbit );
try {
while( true )
{
f.get( (char*)(&indice) ,sizeof(indice));
cout <<"\nNome: " <<indice.nome;
cout <<"\nCognome: " <<indice.cognome;
cout <<"\nIndirizzo: " <<indice.indirizzo;
cout <<"\nNumero: " <<indice.numero;
}
} catch( ios_base::failure )
{ /* fine del file */ }
/* etc */
}
Tre note:
1- codice non testato, non lamentarti se non compila :P :D
2- i dati sono memorizzati "in chiaro" nel file ? (visto l'estensione .txt direi di si') In tal caso non e' consigliato leggere i dati nel modo che fai tu.
3- passi "indice" per valore, forse volevi farlo per puntatore o per riferimento.
Gogeta ss4
23-09-2004, 16:40
Piccolo problema con un ordinamento:
void ordina (rubrica indice,temporaneo temp,temporaneo2 temp2)
{
FILE *fp;
int n,controllo,controllo1,pos;
fp=fopen("rubrica.txt","r+t");
if(fp!=NULL)
{
while(!feof(fp))
{
controllo=fread(&indice,sizeof(indice),1,fp);
if(controllo>0)
{
controllo=fread(&temp,sizeof(temp),1,fp);
if(controllo>0)
{
if(strcmp(indice.nome,temp.nome)>0) //indice.nome > temp.nome
{
pos=ftell(fp)-(sizeof(indice)*2);
//Inizio Scambio
strcpy(temp2.nome,indice.nome);
strcpy(temp2.cognome,indice.cognome);
strcpy(temp2.indirizzo,indice.indirizzo);
strcpy(temp2.numero,indice.numero);
//Fine Scambio su temp 2
//Inizio Scambio temp con indice;
strcpy(indice.nome,temp.nome);
strcpy(indice.cognome,temp.cognome);
strcpy(indice.indirizzo,temp.indirizzo);
strcpy(indice.numero,temp.numero);
//Fine Scambio su Indice
//Inizio Scambio di Tem2 su temp
strcpy(temp.nome,temp2.nome);
strcpy(temp.cognome,temp2.cognome);
strcpy(temp.indirizzo,temp2.indirizzo);
strcpy(temp.numero,temp2.numero);
//Fine Scambio di Temp2 su Temp
//Salvo tutto su file
fseek(fp,pos,0);
if((controllo=fwrite(&indice,sizeof(indice),1,fp)) && (controllo1=fwrite(&temp,sizeof(temp),1,fp)) >0)
{
pos=ftell(fp)-sizeof(indice);
fseek(fp,pos,0);
printf("\nRubrica ordinata correttamente");
printf("\nPremere un tasto per continuare...");
getch();
system("cls");
}
else
{
fclose(fp);
printf("\nErrore nell'ordinamento della rubrica...");
printf("\nPremere un tasto per continuare...");
getch();
system("cls");
}
}
}
}
pos=ftell(fp)-sizeof(indice);
fseek(fp,pos,0);
}
}
fclose(fp);
}
Di ordinare in ordine alfabetico lo fa, però dopo che ordina mi entra in un loop infinito...
Dove sbaglio??
Gogeta ss4
23-09-2004, 18:30
Devo caricare tutte le strutture che ho su file in un vettore, è giusto fare così ??
void ordina (rubrica indice)
{
FILE *fp;
rubrica vettore[500];
int n,i;
fp=fopen("rubrica.txt","r+t");
if(fp!=NULL)
{
while(!feof(fp))
fread(vettore,sizeof(vettore),1,fp);
}
Gogeta ss4
23-09-2004, 20:36
nessuno??
Please e per domani... :cry: :cry:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.