View Full Version : [c++] fread, come si usa?
fabbius69
07-03-2011, 09:31
Sono passato dal turbo pascal al c++
ho creato questa struttura
int main ()
{
struct lot1 {
int num[5][10];
int ind, anno;
char mese[15];
} lot;
FILE * pFile;
pFile = fopen ("d:\pascal\lo96","rb");
return 0 ;
}
Non capisco se il file è binario o no?
come faccia a leggere le struttere memorizzatate nel file e po stamparle?
ho visto fread ma non so come funziona, un aiuto?
Fread è dichiarata in questo modo
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
Il primo parametro è la struttura in cui memorizzare il record.
Il secondo indica la quantità di byte da leggere.
Il terzo indica il numero di letture da effettuare.
Il quarto è una struttura FILE che punta al file binario da leggere.
Si presuppone che se si vuole leggere da un file binario, si sappia la struttura con cui sono memorizzati i record, altrimenti credo che una corretta lettura non sia possibile.
Un esempio pratico.
In questo codice il programma include le funzioni per creare/aprire un file binario, scrivere e leggere.
struct STUDENTE
{
char nome[20];
char cognome[20];
int anni;
};
int main ()
{
FILE * pFile;
STUDENTE stud;
if( (pFile = fopen ( "myfile.bin" , "rb" ) == NULL)
cout<<"Impossibile aprire il file"<<endl;
else
{
while( fread(&stud, sizeof(stud), 1,pFile) > 0)
{
cout<<"Nome: "<<stud.nome<<endl;
cout<<"Cognome: "<<stud.cognome<<endl;
cout<<"Anni: "<<stud.anni<<endl;
}
fclose (pFile);
}
system("pause");
return 0;
}
fabbius69
07-03-2011, 21:48
Grazie sei stato esaudiente, sapresti spiegarmi anche il comando fscanf?
in pascal ho un file di record memorizzati, dici è possibile leggerli in c++?
Mi spiace, ma non so come funzioni scanf().
Dai un'occhiata a questa pagina, magari ti è utilie: http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/
Per i file di pascal credo sia possibile leggerli, a patto però di conoscere la struttura del record memorizzato.
Il motivo è che la lettura funziona in questo modo:
Mettiamo che hai un struttura di questo tipo
struct dipendente
{
char nome[20];
int anni;
char settore;
}
La variabile char nome ovviamente memorizza il nome del dipendente e ha dimensione 20 byte (un char ha dimensione 1 byte, questo è un array di 20 char, quindi 1 byte x 20)
La variabile anni memorizza l'età del dipendente ed essendo un intero ha dimensione 4 byte (se ricordo bene).
Infine la variabile settore ha dimensione 1 byte.
La struttura ha quindi dimensione 25 byte.
Quando usi la funzione fread(), ad ogni lettura il programma legge blocchi di 25 byte, assegna i primi 20 alla variabile nome, i seguenti 4 all'intero anni e l'ultimo byte alla variabile settore.
Va da se che, se non hai la struttura precisa del record memorizzato, la lettura è praticamente impossibile.
fabbius69
08-03-2011, 08:07
Il programma in pascal è stato implementato da me ed ho la struttrura del file record memorizzto, il file memorizzato non ha l'estensione bin la cambo?, ora provero.
Un'ultima domanda se riesco a leggere il file di record del pascal, quale è il comanda che mi fa andare alla fine del file per poter continuare la registrazione.
Grazie
L'estensione non è importante, il file può anche non averla.
Per scrivere in fondo al file ti consiglio di far in questo modo:
Apri il file in questo modo
FILE pFile;
pFIle=fopen("d:\pascal\lo96", "r+b");
Ho cambiato il secondo parametro della funzione fopen. 'r+' significa che il file viene aperto con permessi di lettura e scrittura, il puntatote è posizionato all'inizio e se il file non esiste viene restituito NULL.
In questo modo, fai la lettura del file, e quando hai terminato, sei pronto a scrivere.
Oppure se vuoi subito scrivere in fondo e saltare la lettura fai così
FILE pFile;
if( (pFIle=fopen("d:\pascal\lo96", "r+b")!=NULL)
fseek(pFIle,0,SEEK_SET);
fseek permette di spostarsi all'interno del file. In questo caso ti posiziona alla fine del file.
fabbius69
08-03-2011, 16:42
La dichiarazione della struttura va dentro o fuori del main?
Se nella struttura memorizzata con il pascal la matrice è [1..5,1..10] of integer;
quando la leggo in c++ la matrice va da [0..4,0..9] quindi l'indice [0,0] su c++ equivalerà al [1,1] del pascal?
su questa linea: if( (pFile = fopen ( "d:\pascal\lot69", "rb" ) == NULL) mi da come errore:
Cannot convert 'int' to 'FILE *' in function main()
La dichiarazione della struttura va dentro o fuori del main?
Se nella struttura memorizzata con il pascal la matrice è [1..5,1..10] of integer;
quando la leggo in c++ la matrice va da [0..4,0..9] quindi l'indice [0,0] su c++ equivalerà al [1,1] del pascal?
su questa linea: if( (pFile = fopen ( "d:\pascal\lot69", "rb" ) == NULL) mi da come errore:
Cannot convert 'int' to 'FILE *' in function main()
Hmmm non sono sicuro di aver capito bene, ma per la questione degli indici penso di si.
Per l'errore invece
if( (pFile = fopen ( "d:\pascal\lot69", "rb" )) == NULL)
Mancava una parentesi, colpa mia.
Se ti da problemi anche così, usa questo codice
FILE *pFIle;
pFile = fopen ( "d:\pascal\lot69", "rb" );
if( pFile == NULL)
cout<<"Impossibile aprire il file"
else
{
// codice
}
fabbius69
08-03-2011, 17:27
Ora mi da solo un errore dicendomi:
possible use of 'pFile' before definition in function main
Cosa significa?
tomminno
08-03-2011, 22:05
Ora mi da solo un errore dicendomi:
possible use of 'pFile' before definition in function main
Cosa significa?
Non è che hai scritto il tuo codice fuori dal main o una qualunque altra funzione?
Comunque per rispetto al linguaggio del titolo del thread io userei ifstream al posto della libreria C ;)
fabbius69
08-03-2011, 22:56
#include <iostream.h>
#include <stdio.h>
struct lot1 {
int num[4][9];
int ind, anno;
char mese[15];
};
int main ()
{
FILE *pFile;
lot1 lot;
int n ;
if( (pFile = fopen ( "d:\pascal\lot96.bin" , "rb" )) == NULL)
cout<<"Impossibile aprire il file"<<endl;
else
{
while( fread(&lot, sizeof(lot), 1,pFile) > 0)
{
cout<<"Anno: "<<lot.anno<<endl;
cout<<"Indice: "<<lot.ind<<endl;
cout<<"Mese: "<<lot.mese<<endl;
}
fclose (pFile);
}
for (n=1 ; n <= 10 ; n++)
cout << n << endl;
return 0 ;
}
Ora non mi da più errori ma dice impossibile aprire il file.
Cosa puo significare?
questa è la struttura in pascal
type
lo=array[1..5,1..10]of integer;
nom=string[25];
lot=record
num:lo;
ind:integer;
anno:integer;
mese:string[15];
end;
in pascal la variabile integer occupa due byte, invece char un byte, ho provato in c++ ad usare la variabile short int che occupa 2 byte.
Sempre lo stesso errore.
Cosa puo essere?
potrebbe essere l'array che in pascal parte da 1 invece in c++ da 0?
Usando sizeof sia in pascal che in c++
in pascal mi da 120 in c++ mi da 91, non riesco a capire la differenza.
Mi sa che nell'indirizzo bisogna mettere il doppio slash ( \ ).
Questo è l'if corretto
if( (pFile = fopen ( "d:\\pascal\\lot96.bin" , "rb" )) == NULL)
fabbius69
09-03-2011, 21:04
Mi sa che nell'indirizzo bisogna mettere il doppio slash ( \ ).
Questo è l'if corretto
if( (pFile = fopen ( "d:\\pascal\\lot96.bin" , "rb" )) == NULL)
Giusto il doppio slash.
Il problema che mi stampa tutti numeri strani, la grandezza dei delle due strutture sono differenze, ho problemi con la string[15] che non esiste in c++.
Puoi usare un vettore di char.
Si dichiara così
char text[10];
In questo modo si crea un array composto 10 caratteri.
Ricorda che in c++ ci deve essere almeno un carattere terminatore, ovvero il carattere '\0' (è considerato un unico carattere) che corrisponde al valore 0 in ascii
Quindi se te hai memorizzato stringhe di 15 caratteri col pascal, nella struttura dichiara l'array con 16 variabili char.
fabbius69
10-03-2011, 19:38
Puoi usare un vettore di char.
Si dichiara così
char text[10];
In questo modo si crea un array composto 10 caratteri.
Ricorda che in c++ ci deve essere almeno un carattere terminatore, ovvero il carattere '\0' (è considerato un unico carattere) che corrisponde al valore 0 in ascii
Quindi se te hai memorizzato stringhe di 15 caratteri col pascal, nella struttura dichiara l'array con 16 variabili char.
Provo questa sera quando torno da lavoro, un'altra domanda in delphi io carico queste strutture su un array[1..1000] of lot1; ho provato a scriverlo in c++ma è come se l'array di strutture è troppo grande, massimo posso scrivere [1..500] ora stu usando il turbo c++ 4.5, con il borland 6 c++ l'array più grande si puo creare? mi servono almeno 1000 strutture memorizzate in array per fare dei calcoli, come li devo dichiarare con malloc?
tomminno
10-03-2011, 21:25
Provo questa sera quando torno da lavoro, un'altra domanda in delphi io carico queste strutture su un array[1..1000] of lot1; ho provato a scriverlo in c++ma è come se l'array di strutture è troppo grande, massimo posso scrivere [1..500] ora stu usando il turbo c++ 4.5, con il borland 6 c++ l'array più grande si puo creare? mi servono almeno 1000 strutture memorizzate in array per fare dei calcoli, come li devo dichiarare con malloc?
Già che parliamo di C++ usa vector al posto degli array del C, oppure, se hai a disposizione un compilatore recente, la classe array.
Infine mai usare malloc in C++
fabbius69
10-03-2011, 21:34
Ora mi stampa le strutture ma per i mesi rimangono sempre le ultime lettere del mese prima
ad esempio febbraio quando passa a marzo scrive marzoio, rimangono io di Febbraio.
Scusa per array scritto in pascal, stavo scrivendo a lavoro e no mi ricordavo come si scriveva in c++.
Dicevo volevo caricare le strutture almeno mille su un vettore lot1 numv[1000];
ho scoperto che è troppo grande mi da errore: array size too large.
Ora sto usando turbo c++ 4.5
Come posso risolvere questo problema provando con un'altro compilatore più recente oppure??
Mi spieghi le classi di array???
tomminno
10-03-2011, 21:56
Ora mi stampa le strutture ma per i mesi rimangono sempre le ultime lettere del mese prima
ad esempio febbraio quando passa a marzo scrive marzoio, rimangono io di Febbraio.
[quote]
Perchè tra una lettura e l'altra non resetti il contenuto degli array di lot1.
[quote]
Scusa per array scritto in pascal, stavo scrivendo a lavoro e no mi ricordavo come si scriveva in c++.
Dicevo volevo caricare le strutture almeno mille su un vettore lot1 numv[1000];
ho scoperto che è troppo grande mi da errore: array size too large.
Ora sto usando turbo c++ 4.5
Come posso risolvere questo problema provando con un'altro compilatore più recente oppure??
Turbo C++ 4.5 dovrebbe essere un compilatore dell'ante-guerra risale a prima del 1995. Io proverei con Visual Studio 2010 Express.
Mi spieghi le classi di array???
Usa vector che è una classe template per contenere sequenze di elementi di dimensione variabile, con la caratteristica di essere (l'unica classe STL) compatibile con gli array del C.
std::vector<lot1> v;
v.push_back(LeggiLot());
fabbius69
11-03-2011, 15:52
Programmando in console è meglio il dev c++ oppure il visual c++?
tomminno
11-03-2011, 16:47
Programmando in console è meglio il dev c++ oppure il visual c++?
Qualunque cosa è meglio di devc++.
Ovviamente essendo su Windows non c'è niente di meglio di Visual Studio.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.