webForumDet fria alternativet

Spara vector

9 svar · 600 visningar · startad av PatrikH

PatrikHMedlem sedan juli 200114 inlägg
#1

Är det någon som har en aning om hur man sparar vectorer i en binärfil. Då jag gör detta så blir det fel hela tiden, tror det har någonting med minnesadresser attt göra.

Jag har följande strukturer

struct bokstav
{
   char tkn;
   int varde;
};

struct mall
{
   vector<bokstav> lettercount;
};

mall CS;

char file[10] = "stats.txt";
ofstream fout;
fout.open(file, ios_base::out | ios_base::app | ios_base::trunc | ios_base::binary);

fout.write((char*) &CS, sizeof CS);

Men när jag sedan läser in filen så stämmer inte värdena (t.ex. varde). Om jag har förstått det hela rätt så är det någonting med sizeof som spökar, då denna inte tar hänsyn till storleken på alla "fack" som vectorn skapar.

Någon som vet hur jag ska göra??

SweyMedlem sedan apr. 20002 000 inlägg
#2

Du får gå igenom varje post i vektorn och spara varje post med ett eget write.

Eftersom vektorn använder minne som är allokerat på heapen är det enda sättet.

PatrikHMedlem sedan juli 200114 inlägg
#3

OK, men hur gör jag det då?? Har testat i snart en timme men får ingenting att fungera, suck!

SPiNMedlem sedan mars 20005 832 inlägg
#4

Kan man inte på något sätt serialisera objekt/strukturer i C++? Jag kanske bara har drömt det... :)

SweyMedlem sedan apr. 20002 000 inlägg
#5

Vad är problemet? Att gå igenom vektorn eller att spara?

Testa något liknande.

for(int i = 0; i < vektorn.size(); i++)
fwrite((char*)&vektorn[i], sizeof bokstav);

Du bör också spara antalet poster för att sedan kunna läsa in det med read.

Jag känner inte till något om serialisering med STL, men bl.a. MFC har stöd för det.

PatrikHMedlem sedan juli 200114 inlägg
#6

Tack för all hjälp, nu har jag fått det att fungera någorlunda iaf.
Är dock fortfarande ett problem:

Varför kan man inte göra så här och hur ska man göra annars??

void s_stat(mall ut)             
{
   char file[10] = "stats.txt";
   ofstream fout;
   fout.open(file, ios_base::out | ios_base::app | ios_base::trunc | ios_base::binary);

   fout.write((char*) &CS, sizeof CS);

   for(int i=0; i<CS.lettercount.size(); i++)
      fout.write((char*)&CS.lettercount[i], 8);

   fout.close();
}

void o_stat(void)
{
   char file[10] = "stats.txt";
   ifstream fin;
   fin.open(file, ios_base::in | ios_base::binary);

   fin.read((char*) &AS, sizeof AS);

   streampos posin = fin.tellg();
   fin.seekg(posin);

   for(int i=0; i<AS.lettercount.size(); i++)
      fin.read((char*)&AS.lettercount[i], 8);

   fin.close();

Det fungerar bra så länge jag inte skriver ut/läser in CS/AS

PeWMedlem sedan juni 20006 839 inlägg
#7

Tja.. detta var en salig blandning mellan c++ och c :l men du bör väl använda den mall-kopian (ut) du får skickar med som argument i "void s_stat(mall ut)" för att plocka den datan du ska spara... fast egentligen bör du nog köra med en pekare ;)
Sen... vad gör du med AS (hur kommer du åt den) :q

Det här går ju att göra betydligt smidigare med lite klasser :i

Typcirkaungefär->

klass tecken:
     - char
     - int
      skriv(std::ostream &o){ o << char << int }
      läs(std::istream &i){ i >> char >>int }

Eftersom du ska peta i en vektor så antar jag att det är flera "tecken" som ska sparas. Så det smidigaste är att dessa tecken har var sin egna filhanteringsmetoder och sen är det bara att öppna filen och köra på igenom vectorn för att skriva till filen och sen det omvända när du ska läsa in. Det enda "knepiga" med detta är att du bör destruera objekten genom att loopa vektorn.

Har du sen flera varianter av teckenobjekt kan du ju göra ovan klass abstrakt och genom virtual och bygga dessa vidare från denna och på det viset bara mosa på med en enda datatyp på alla objekt.

:birp

PatrikHMedlem sedan juli 200114 inlägg
#8

Ja det kan ju kanske vara något. Nu har jag fåttt det att fungera som det var tänkt iaf. Inte så värst effektivt kanske, vore ju smidigt om digraphcount, trigraphcount och lettercount kunde skrivas som en "enhet".


struct bokstav
{
   char tkn;
   int varde;
};

struct mall
{
   vector<bokstav> lettercount;
   int digraphcount[total][total];
   int trigraphcount[total][total][total];
   unsigned int totallength;
};

mall CS;
mall AS;

bla bla bla...

void o_stat(void)
{
   char file[10] = "stats.txt";
   ifstream fin;
   fin.open(file, ios_base::in | ios_base::binary);

   for(int i=0; i<AS.lettercount.size(); i++)
      fin.read((char *)&AS.lettercount[i], 8);

   fin.read((char *)&AS.digraphcount, sizeof AS.digraphcount);
   fin.read((char *)&AS.trigraphcount, sizeof AS.trigraphcount);
   fin.read((char *)&AS.totallength, sizeof AS.totallength);

   fin.close();
}

void s_stat(mall *ut)
{
   char file[10] = "stats.txt";
   ofstream fout;
   fout.open(file, ios_base::out | ios_base::app | ios_base::trunc | ios_base::binary);

   for(int i=0; i<ut->lettercount.size(); i++)
      fout.write((char *)&ut->lettercount[i], 8);

   fout.write((char *)&ut->digraphcount, sizeof ut->digraphcount);
   fout.write((char *)&ut->trigraphcount, sizeof ut->trigraphcount);
   fout.write((char *)&ut->totallength, sizeof ut->trigraphcount);

   fout.close();
}
SweyMedlem sedan apr. 20002 000 inlägg
#9

Varför använder du en vector om antalet poster är konstant? Då kan du lika gärna använda en statisk array. Om antalet inte är konstant måste du ändra inläsningskoden.

PeWMedlem sedan juni 20006 839 inlägg
#10

Inte så värst effektivt kanske, vore ju smidigt om digraphcount, trigraphcount och lettercount kunde skrivas som en "enhet".

Precis det som blir kontentan av det jag exemplifierade med tillägget att du gör en basklass som regerar över alla under klasser och sen bara slussar du data in/ut från filen :bire

Genererad på 379 ms · cache AV · v20260730165559-full.f96bc7eb