Avatar billede noerbo Nybegynder
13. juli 2012 - 00:08 Der er 9 kommentarer og
1 løsning

Gem klasse i fil

Hej Eksperter

  Jeg er ved at lave en klasse, der har i/o metoder til filer.

  Følgende kode virker som forventet

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

class Foo {
public:
  Foo(int _i, string _str) {
    i = _i;
    str = _str;
  }
  ~Foo(void) {

  }
  void print(void) {
    cout<<"str: " << str <<endl;
    cout<<"i : " << i <<endl;
  }

  void save(void) {
    // Gem til fooFile
    ofstream outFile("fooFile.dat",ios::binary);
    outFile.write((char*)(this), sizeof(Foo));

    outFile.close();

  }

  void load(void) {
    // Indlæs fra fooFile
    ifstream inFile("fooFile.dat",ios::binary);

    inFile.read((char*)(this), sizeof(Foo));

    inFile.close();

  }

private:
  int i;
  string str;
};

int main() {
  Foo* foo = new Foo(42, "The answer");
  Foo* foo2 = new Foo(0, "");
    foo->save();

  foo2->load();

  foo2->print();
  return 0;
}

Hvis jeg derimod først kører ovenstående program og fjerner delen af main, der skriver til filen får jeg en segmentation fault. (altså filen der skal læses fra er oprettet) Så main bliver

int main() {
//  Foo* foo = new Foo(42, "The answer");
  Foo* foo2 = new Foo(0, "");
//    foo->save();

  foo2->load();

  foo2->print();
  return 0;
}

Egentligt har jeg 2 spørgsmål
1) Hvorfor virker det første eksempel, men det andet hvor der udelukkende indlæses ikke?
2) Hvad skal rettes til for at det virker?
Avatar billede arne_v Ekspert
13. juli 2012 - 00:15 #1
maaske skulle du teste med:

ifstream inFile("fooFile.dat",ios::binary);
if(inFile.good())
{
    inFile.read((char*)(this), sizeof(Foo));
    inFile.close();
}
Avatar billede noerbo Nybegynder
13. juli 2012 - 00:19 #2
inFile.good() returnerer true, men inFile.read() giver stadig en segmentation fault. inFile.close() giver dog ingen problemer.
Avatar billede arne_v Ekspert
13. juli 2012 - 00:21 #3
jeg ville skrive og laese de 2 felter fremfor this, men i denne her kontekst boer this virke

hvilken compiler med hvilke options?
Avatar billede noerbo Nybegynder
13. juli 2012 - 00:31 #4
g++ under ubuntu 12.04. Jeg har ikke selv sat nogle flag.

Grunden til at jeg gør det på denne måde er at jeg gerne senere vil kunne tilføje nye ting uden at skulle ændre i save/load metoderne.
Avatar billede arne_v Ekspert
13. juli 2012 - 04:40 #5
Jeg tror ikke paa metoden.

Hvis:

string str;

allokerer noget udenfor Foo, saa loader du en pointer som peger paa noget som ikke er der.
Avatar billede noerbo Nybegynder
13. juli 2012 - 11:00 #6
Ja det kan du have ret i. Havde ikke lige overvejet at string nok vile give problemer med pointeren. Så giver det også god mening at eksempel 1 virker, men ikke eksempel 2.

  Ved du om der er en smart løsning, der kan det jeg gerne vil eller vil det være nemmere bare at udskrive variablerne en for en og så rette til løbende?
Avatar billede arne_v Ekspert
13. juli 2012 - 23:58 #7
Jeg er bange for at du maa lave det manuelt. Ingen mulighed for reflection.
Avatar billede noerbo Nybegynder
14. juli 2012 - 02:50 #8
Efter lidt søgning på google fandt jeg ud af at boost biblioteket kan løse problemet forholdsvis nemt
http://www.ibm.com/developerworks/aix/library/au-boostserialization/index.html

Men mange tak for hjælpen med at opklare, hvorfor mit første eksempel ikke virkede arne_v. Kan jeg få dig til at smide et svar?
Avatar billede arne_v Ekspert
14. juli 2012 - 04:55 #9
Du skal stadig skrive kode ifoelge "Serializing your own types".
Avatar billede arne_v Ekspert
14. juli 2012 - 04:55 #10
og svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester