PDA

View Full Version : [C++] Salvataggio di strutture in file


uReverendo
30-07-2007, 11:49
Devo salvare (e leggere) una stuttura su file. Purtroppo non posso farlo direttamente perchè la struttura contiene un campo string, quindi ho pensato di usare questo metodo:


struct Persona
{
int iUnk1;
int iUnk2;
unsigned char bMd5[16];
string strNome;
};

bool ReadFile(string strFile, vector<Persona> &vp)
{
ifstream f;
unsigned int uiszStruct;
Persona p;

f.open(strFile.c_str(),ios::binary);

if(!f)
{
cout << "Errore" << endl;
return false;
}

uiszStruct = sizeof(Persona) - sizeof(string);

while(!f.eof())
{
f.read((char *)&p, uiszStruct);
ReadString(f, p.strNome);

if(f.good())
{
vp.push_back(p);
}
}
}

bool WriteFile(string strFile, vector<Persona> &vp)
{
ofstream f;
unsigned int uiszStruct;

f.open(strFile.c_str(),ios::binary);

if(!f)
{
cout << "Errore" << endl;
return false;
}

uiszStruct = sizeof(Persona) - sizeof(string);
for(int i=0; i<vp.size(); i++)
{
f.write((char *)&vp[i], uiszStruct);
WriteString(f,vp[i].strNome);
}

}


Così funziona, però è corretto fare in questo modo o si possono verificare dei problemi? Alternative? (oltre al salvataggio campo per campo)

Infine i compilatori allocano SEMPRE i campi della struttura nell'ordine in cui vengono dichiarati (in questo caso int - int - unsigned char - string) oppure a seguito di qualche ottimizzazione l'ordine può essere stravolto?

uReverendo
31-07-2007, 11:02
up

E' corretto salvare un struttura in questo modo?

cionci
01-08-2007, 09:34
Dovrebbe andare bene perché la stringa è in fondo alla struttura dati.
Se non lo fosse ti converrebbe salvare e rileggere comunque anche la stringa e successivamente salvare e rileggere la stringa come fai ora.

uReverendo
01-08-2007, 10:47
Ok, grazie :)

uReverendo
04-08-2007, 12:06
Ho fatto altre prove e purtroppo non sembra andare bene (uso il visual studio 2005).

Ho notato che quando uso strutture che contengono campi a 64 bit (__int64) il compilatore tende ad allineare tutti i membri a 64 bit con il risultato che la dimensione della struttura non sempre coincide con la somma delle dimensioni dei singoli membri. Nel mio caso se il compilatore decide di aumentare la dimensione del campo string ottengo risultati imprevisti.

Salvare tutta la struttura come mi ha suggerito cionci lo escludo sia perchè la classe string il modalità debug è grande 32 Byte mentre in release è qrande 28 Byte, sia per evitare di sprecare spazio (le strutture da salvare sono parecchie migliaia)

Per risolvere il problema ho pensato di raggruppare i membri fissi in un'altra struttura e salvare direttamente quella:

struct Persona_Dati
{
int iUnk1;
int iUnk2;
unsigned char bMd5[16];
};
struct Persona
{
Persona_Dati Dati;
string strNome;
};

Che ne pensate?

P.S. La struttura che ho postato è solo un esempio, quella reale è molto più grande.