Toon posts:

[C++][MFC] Variabelen opslaan in bestand

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ja, je raad het goed, ik heb een vraag. Ik ben bezig met een programmaatje waarbij je een quiz kunt doent.

Ik heb door middel van de App-wizard in Visual C++ een MFC project aangemaakt en de Base Class is CView. Bij het programma zelf kun je via een menu-optie een dialoog openen. In het dialoog kun je een aantal persoonsgegevens invullen en een drietal Quiz-vragen beantwoorden. Hierna worden in een aparte klasse de gegevens verwerkt en met een methode toString op het scherm getoond.

C++:
1
2
3
4
5
6
7
8
9
CString CBepaalResultaat::toString()
{
    CString string;
    string += "naam: " + naam;
    string += " leeftijd: " + leeftijd;
    string += " geslacht: " + geslachtGebruiker + " score: ";
    string += aantalVragenCorrect;
    return string;
}


Nu wil ik deze gegevens, dus het resultaat, opslaan in aparte bestanden. Ik kan alwel bestanden opslaan en deze krijgen de extensie .quiz. Wanneer ik de boel opsla worden de waarden van de variabelen niet meegenomen.

Hoe kan ik ervoor zorgen dat deze waarden wel correct worden opgeslagen? Ik heb begrepen dat de methode Serialize(CArchive& ar) bestaat voor het opslaan van objecten, maar in dit geval gaat het niet om objecten maar voornamelijk om variabelen van het type CString. Het is me ook niet gelukt om een object te maken zodat ik de methode serialize wel kan gebruiken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:32
Toon eens wat code die je gebruikt voor het opslaan.

afaik kan je mbhv die Serialize method ook strings ed gaan opslaan:

code:
1
2
3
4
5
6
7
8
if( ar.IsStoring() )
{
   ar << naam << leeftijd << geslacht << aantalvragencorrect;
}
else
{
   ar >> naam >> leeftijd >> geslacht >> aantalvragencorrect;
}

Zoiets ongeveer moet toch lukken ?

Verder heb ik zo'n beetje het gevoel dat je al wilt kunnen lopen voordat je kan gaan ...

[ Voor 22% gewijzigd door whoami op 07-02-2005 14:46 ]

https://fgheysels.github.io/


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Yep, als je geen object kunt aanmaken in geheugen dan wordt het wat lastig om 3 objecten te serializen. Voor alle duidelijkheid: naam, leeftijd en geslachtGebruiker zijn al drie objecten, van type CString. Of bedoel je dat je geen types kunt maken?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
MSalters schreef op maandag 07 februari 2005 @ 22:52:
Yep, als je geen object kunt aanmaken in geheugen dan wordt het wat lastig om 3 objecten te serializen. Voor alle duidelijkheid: naam, leeftijd en geslachtGebruiker zijn al drie objecten, van type CString. Of bedoel je dat je geen types kunt maken?
Het zijn geen objecten, maar gewoon variabelen van het type CString. Zo is de variabele naam bijvoorbeeld gedeclareerd.

C++:
1
CString naam;


Maar volgens mij wil ik idd lopen voordat ik kan gaan want heb helemaal geen code geschreven voor het opslaan. Beetje lastig allemaal omdat ik dit nog nooit eerder heb gedaan en ook geen goede uitleg hierover heb.

  • The End
  • Registratie: Maart 2000
  • Laatst online: 08:30

The End

!Beginning

Verwijderd schreef op woensdag 09 februari 2005 @ 15:02:
[...]


Het zijn geen objecten, maar gewoon variabelen van het type CString. Zo is de variabele naam bijvoorbeeld gedeclareerd.

C++:
1
CString naam;


Maar volgens mij wil ik idd lopen voordat ik kan gaan want heb helemaal geen code geschreven voor het opslaan. Beetje lastig allemaal omdat ik dit nog nooit eerder heb gedaan en ook geen goede uitleg hierover heb.
Een CString is ook een object.

Even een simpel voorbeeld van het gebruik van Archives:

Saven:
C++:
1
2
3
4
5
6
CString MyString;
CFile MyArchiveFile(_T("MyArchive.dat"),CFile::modeWrite  | CFile::modeCreate);
CArchive Archive(&MyArchiveFile,CArchive::store);
Archive << MyString;
Archive.Close();
MyArchiveFile.Close();


Laden:
C++:
1
2
3
4
5
6
CString MyString;
CFile MyArchiveFile(_T("MyArchive.dat"),CFile::modeRead);
CArchive Archive(&MyArchiveFile,CArchive::load);
Archive >> MyString;
Archive.Close();
MyArchiveFile.Close();


Edit: Bij dit voorbeeld moet je wel even opletten dat er try/catch omheen moet voor foutafhandeling.

[ Voor 13% gewijzigd door The End op 09-02-2005 15:51 . Reden: Code was niet helemaal goed :) ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
De TS heeft moeite met het onderscheid tussen class en object, dan is dit geen handige
opmerking 8)7

CString is een class. Kijk maar in de header.

Wat je bedoelt is: Een CString object is ook een object.

Objecten kunnen const of niet-const zijn, het tweede soort wordt vaak variabele
genoemd. Voor het serializen maakt const helemaal niets uit.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • The End
  • Registratie: Maart 2000
  • Laatst online: 08:30

The End

!Beginning

MSalters schreef op woensdag 09 februari 2005 @ 15:42:
[...]

De TS heeft moeite met het onderscheid tussen class en object, dan is dit geen handige
opmerking 8)7

CString is een class. Kijk maar in de header.

Wat je bedoelt is: Een CString object is ook een object.

Objecten kunnen const of niet-const zijn, het tweede soort wordt vaak variabele
genoemd. Voor het serializen maakt const helemaal niets uit.
Ik denk dat ik je niet helemaal begrijp?

Zij doet dit in Haar code: 'CString string'. Ze maakt een object aan van het type CString. Oftwel ze maakt een instantie van de class CString. Anders bestaat de CString helemaal niet.

Of ze const of niet zijn heeft niks te maken met of het een object is? Dat zegt alleen of je hem mag wijzigen of niet dacht ik zo.

const objecten kunnen in ieder geval niet geserialized worden. (of je moet gaan typecasten)

[ Voor 9% gewijzigd door The End op 09-02-2005 16:04 . Reden: Geslachtsverandering... ]


Verwijderd

Topicstarter
MSalters schreef op woensdag 09 februari 2005 @ 15:42:
[...]

De TS heeft moeite met het onderscheid tussen class en object, dan is dit geen handige
opmerking 8)7
Ik heb op zich helemaal geen problemen met verschil tussen class en object, alleen met C++ (Ik neem aan dat TS, topic starter is). :P
The End schreef op woensdag 09 februari 2005 @ 15:48:
[...]
Hij doet dit in zijn code: 'CString string'. Hij maakt een object aan van het type CString. Oftwel hij maakt een instantie van de class CString. Anders bestaat de CString helemaal niet.
Oe, heb ik een verassing voor jou zeg ;) Het is "zij" en "haar"

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
The End schreef op woensdag 09 februari 2005 @ 15:48:
[...]
Ik denk dat ik je niet helemaal begrijp?

Zij doet dit in Haar code: 'CString string'. Ze maakt een object aan van het type CString. Oftwel ze maakt een instantie van de class CString. Anders bestaat de CString helemaal niet.
Het probleem wat ik met je woorden heb is dat "De CString" onduidelijk is, omdat je niet zegt welk van de twee je bedoelt: "De CString class" of "Het CString object". Je bedoelt het laatste, maar dat is niet helemaal helder.

In elk geval bestaat de CString class ook als je geen CString objecten hebt.
Of ze const of niet zijn heeft niks te maken met of het een object is? Dat zegt alleen of je hem mag wijzigen of niet dacht ik zo.
Klopt. "variabelen" zijn de subset van "objecten" die je kunt wijzigen.
const objecten kunnen in ieder geval niet geserialized worden. (of je moet gaan typecasten)
Fout, dat kan best. MFC zou in theorie er moeite mee kunnen hebben, maar de standaard C++ library kan het gewoon.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • The End
  • Registratie: Maart 2000
  • Laatst online: 08:30

The End

!Beginning

MSalters schreef op woensdag 09 februari 2005 @ 18:40:
[...]

Het probleem wat ik met je woorden heb is dat "De CString" onduidelijk is, omdat je niet zegt welk van de twee je bedoelt: "De CString class" of "Het CString object". Je bedoelt het laatste, maar dat is niet helemaal helder.

In elk geval bestaat de CString class ook als je geen CString objecten hebt.
Ja idd. We begrijpen elkaar :) Ik had het een beetje kort door de bocht geschreven.

[knip]
Fout, dat kan best. MFC zou in theorie er moeite mee kunnen hebben, maar de standaard C++ library kan het gewoon.
Ik heb het gewoon getest met de MFC versie en daar werkt het niet bij. Ik wist niet dat er ook standaard C++ functies voor waren, maar het lijkt me dat je niet vanuit een file naar een const object kan serializen. Dan is hij immers niet meer const.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Duh, nee, van file naar object heet deserializen. Dat deel werkt niet naar const objecten, wat overigens de reden is dat ik het MFC deserializing pattern suboptimaal vindt. iostreams heeft hetzelfde probleem in mindere mate, alleen is daar geen equivalent van ar.isStoring( ). Je gebruikt daar op alle nivo's << en >> ipv een bool. Dat maakt const-kwalificatie iets handiger.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Het probleem met de serialisatie in MFC is inderdaad isStoring(). CObject heeft maar een methode serialize:
C++:
1
virtual void Serialize( CArchive& ar );
Er is geen const versie van, deze moet zowel lezen als schrijven. In principe is het onmogelijk met deze method om const objecten te serializen (laat staan deserializen), ook al wordt het object (hopelijk) niet veranderd als isStoring true is, de compiler kan dit nooit runtime weten en zal echt een const modifier moeten hebben.

MFC lost dit uiteraard weer eens met een minder nette method op, de >> en << operators van CArchive roepen respectievelijk de protected methods ReadObject en WriteObject aan, en deze roepen beiden Serialize aan. Operator << en WriteObject nemen beiden een const CObject aan, maar uiteindelijk cast WriteObject het met een C cast naar een (non-const) CObject *, en roept Serialize daar op aan.

Je zou op deze manier dus via de Serialize functie een const object kunnen wijzigen zonder dat je het door hebt. Daar ontkom je niet aan met MFC's aanpak, dat had wat mij betreft ook wel wat beter in elkaar kunnen zitten.

[ Voor 11% gewijzigd door madwizard op 10-02-2005 10:32 ]

www.madwizard.org


Verwijderd

Topicstarter
Ik heb inmiddels een oplossing voor mijn probleem. Als jullie het niet erg vinden ga ik de oplossing niet posten want is nogal een stuk code. Ik wou idd een beetje te snel gaan hierbij.

Bedankt voor de hulp iig!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als jullie het niet erg vinden ga ik de oplossing niet posten want is nogal een stuk code
Je hoeft niet alles te posten, maar het zou wel fijn zijn voor anderen met een soortgelijk probleem als ze ongeveer weten in welke hoe ze het moeten zoeken :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1