Gå til innhold

Lagre og hente struct /m vector i fil


Anbefalte innlegg

Eg har fulgt følgende tutorial; http://www.codersource.net/cpp_file_io_binary.html , og har støtt på et lite problem som eg ikkje ser løsning på.

 

Eg hadde ønske om å lagre en vector i struct'en som skal lagres og leses fra filen, som vist i følgende kode:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

struct structure
{
char id[50];
vector<char*> object;
};

int main(){
structure saveStruct;

fstream output("test.txt", ios::out);

strcpy_s(saveStruct.id, "ID1");
saveStruct.object.push_back( "object1" );
saveStruct.object.push_back( "object2" );

output.write(reinterpret_cast<char *>(&saveStruct), sizeof(saveStruct));
output.close();

fstream input("test.txt", ios::in);

structure loadStruct;

input.read(reinterpret_cast<char *>(&loadStruct), sizeof(loadStruct));

input.close();

cout << loadStruct.id << endl;

system("pause");

return 0;

}

 

Eg bruker Visual C++ 2005 Express Edition, og får følgende feilmelding etter eg trykker forbi "pause"'en, som eg håper eg kunne fått litt hjelp i å forstå;

 

Debug Assertion Failed!

 

Program: ...

File: dbgdel.cpp

Line: 52

 

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

 

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

 

Hvis eg fjerner vectoren går programmet fint uten problemer. Har og prøvd med string type istedenfor char*, får da feilmelding:

 

Unhandled exception at 0x10252758 in test.exe: 0xC0000005: Access violation reading location 0xfeeefee2.

 

Har i tillegg forsøkt å lage en vanlig char array istedenfor vector som følger;

char object[][50];

og lagt data i arrayet slik;

strcpy_s(saveStruct.object[0], "object1" );

strcpy_s(saveStruct.object[1], "object2" );

 

Men nok ein gong får eg ein feilmelding:

Run-Time Check Failure #2 - Stack around the variable 'saveStruct' was corrupted.

 

 

Er ganske ny på C++, og må si eg ikke forstår hvorfor dette går galt, og håpte kanskje noen litt mer erfarne programmerere på forumet kunne forklart meg hva eg eventuellt gjør galt og hvorfor går galt?

Endret av _TT_
Lenke til kommentar
Videoannonse
Annonse

Etter det jeg ser så bruker du vector på feil måte.

Som man leser på siden du linket til så brukes ikke vectorer der.

write skriver fra pekeren [reinterpret_cast<char *>(&saveStruct)] og så leser den byte for byte til sizeof(saveStruct) = antall byte skrivd.

Men med vector kan man ikke regne med at elementene ligger etterhverandre.

At det overhode går å lese det igjen er mer flaks.

 

Det jeg tror! skjer er at du egentlig kopiere vectoren dvs så når den andre vectoren leses inn så blir all dataen pekerer og tekst stringer kopiert (litt usikker på om stringene blir lest) så når det er tid for å stenge ned så prøver begge og fjerne samme allokerte minne så når den andre vil unalokere minne for andre gang klikker det.

 

Det du må gjøre er å lage en loop som skriver ut hvert av elementene hver for seg..

Og du må selvsagt lese de hver f

 

Beklager at jeg ikke har tid til å skrive mer nå, men jeg skal prøve å skrive mer senere.

 

EDIT:

Det virker som om det ikke blir skrivd ut noe tekst (utenom saveStruct.id), men heller pekere til dataene i minnet, noe som vil gjøre at du overhode ikke lagrer noe fornuftig data (utenom saveStruct.id).

Du leser med andre ord posisjonen til teksten i minnet.

 

Håper det hjelper

 

Lykke til

Endret av Giddion
Lenke til kommentar

Grunnen til at eg ville ha vector/array i structen som lagres i fila var at eg ville ha forskjellig antall stringer i hver av vectorene, og vil da være litt kinkig å måtte ha variabler for hver.

 

Som sagt så er eg litt ny i C++, og står litt uforstående til hvordan eg skal klare å få dette til, eller om det i det hele tatt er mulig å lagre vectorer på en slik måte som dette i filer?

Lenke til kommentar

Det er fult mulig å gjøre det du vil (holder selv på med lignende prosjekt for tiden), men det er nok litt vanskeligere enn koden din. Det blir særlig mer arbeid hvis du ikke vet størrelsen på dataene du vil lese.

Den beste teknikken er å tenke deg at du ikke vet noe om hvor store dataen er.

 

her er et eksempel på hvordan filen kan organiseres

eks.

1 antall vektorer

___2 størrelsen på vector n

___3 antall stringer i vector n

______4 størrelsen på string m

______5 dataene fra string m

______6 størrelsen på string o

______7 dataene fra string o

______8 dataene fra string m

___9 størrelsen på vector p

___10 antall stringer i vector p

______11 størrelsen på string m

______12 dataene fra string m

 

hvis du trenger litt mer hjelp kan jeg sikkert prøve å lage et eksempel

Endret av Giddion
Lenke til kommentar

Du kan ikke skrive hele vector-objektet rett til fil slik du gjør (Giddion påpekte vel også dette). Grunnen er at vector inneholder interne pekere som ikke vil være gyldige neste gang du leser de inn.

 

Det er generelt fy fy og ris på det ene og det andre m.m. for å skrive/lese hele klasseobjekter slik du gjør.

 

Men du kan derimot skrive en array vector holder direkte. std::vector er den eneste containeren som elementene er garantert å ligge etterhverandre. Men det hjelper ikke hvis vectoren i seg selv holder pekere. Hvis den hadde inneholdt char hadde det vært noe annet, f.eks:

 

std::vector<char> myVec;
//... add some elements to myVec
output.write(&myVec[0], myVec.size() );

 

Koden over er helt ok.

Endret av kjetil7
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...