Struct speichern?

Thomasio

Erfahrenes Mitglied
Meine Anwendung hat eine config.ini Datei, die sie beim Start liest und am Ende wieder speichert.
Da speichere ich ein paar Variablen, wie z.B. Fenstergrösse und -position, so dass beim nächsten Start die Anwendung genau da wieder öffnet, wo sie zuletzt geschlossen wurde.
Im Programm sind das natürlich int Werte, in der Datei aber char*, darum nutze ich atoi() und itoa() um das beim lesen/schreiben umzuwandeln.

Nun möchte ich gerne ein ganzes struct speichern und wieder lesen, genauer gesagt einen HFONT

Wenn ich also habe:

HFONT MyFont = CreateFont( ... irgendwas ...);

wie konvertiere ich das bei Programmende zu char* und schreibe es in die config.ini, und wie lese ich das bei Programmstart wieder aus, so dass ich es wieder zu HFONT konvertieren kann?
 
Falls in der Struktur keine Pointer auf dynamisch allokierte Sachen etc sind, kannst du den char*-Pointer einfach mit (char*)(&myFont) bekommen.
Die Anzahl der zu lesenden/schreibenden Bytes bekommst du mit sizeof(HFONT).

Wenn besagte dynamisch allokierte Pointer drinnen sind, müssen der Inhalt noch extra behandelt werden.
 
Erstmal danke, das müsste fürs schreiben reichen.

Aber wie lese ich das wieder ein?
Sprich wenn ich aus der Datei char* gelesen habe, wie mache ich da wieder HFONT draus?
 
Aufs HFONT machst du zuerst einen charpointer drauf und liest dann das ganze in ein, als wäre das ganze ein normales char Array.

Zeig einmal, wie du es eigentlich schreibst.
 
Hallo Thomasio,

HFONT ist ein Handle, das von Windows verwaltet wird und intern mit Speicherbereichen korrespondiert, auf die du keinen Zugriff hast. Daher bietet es sich an, eine LOGFONT-Stuktur zu speichern, die alle Parameter zusammenfasst.

Gruß
MCoder
 
Bisher schreibe ich das gar nicht, weil ich nicht weiss wie.
Ich schreibe die Datei mit (Fehlerprüfungen mal weggelassen):

Code:
RECT rect;
GetWindowRect(hwnd,&rect);
stringstream s;
s << rect.left << " " << rect.top << " " << rect.right << " " << rect.bottom << " " << "NochEinPaarWerte";
string t = s.str();
HANDLE hFile;
DWORD dwWritten;
hFile = CreateFile("config.ini",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
WriteFile(hFile,t.c_str(),t.size(),&dwWritten,0);
CloseHandle(hFile);

und gelesen wird sie dann wieder so:

Code:
DWORD dwFileSize;
HANDLE hFile = CreateFile("config.ini",GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
dwFileSize = GetFileSize(hFile,0);
char buffer[dwFileSize+1];
DWORD dwRead;
ReadFile(hFile,buffer,dwFileSize,&dwRead,0);
CloseHandle(hFile);

stringstream s(buffer);
string temp;
vector<int>Details;
while(getline(s,temp,' '))
{
Details.push_back(atoi(temp.c_str()))
}
MoveWindow(hwnd,Details[0],Details[1],Details[2] - Details[0],Details[3] - Details[1],1);
int NochNeVariable = Details[4];
// usw.

Mir ist schon klar, dass ich den vector<int> nicht so behalten kann, weil das struct da nicht rein passt, auch die Leerstelle als Trennzeichen muss ich evtl ändern, je nachdem, was im struct an Zeichen vorkommen kann.

Das Ganze ist schlicht Neuland für mich, weil ich beim lesen und schreiben von Dateien noch nie was anderes als einfachen Text oder konvertierte int verwendet habe.
 
Hallo

Wenn die ini-Datei nicht unbedingt lesbar sein muss geht es natürlich viel billiger so:

Code:
hFile = CreateFile(_T("config.ini"),GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

WriteFile(hFile,&rect ,sizeof(RECT),&dwWritten,0);
Ansonsten könnte man die Struktur auch komplett in hex-code umwandeln.

VG
merano
 
Das geht nur, solange in der Datei nur ein Wert, bzw. ein struct drin steht, aber ich brauche etwa ein Dutzend Werte, samt Trennzeichen, so dass ich sie beim einlesen via getline() wieder auseinander nehmen und den entsprechenden Variablen zuordnen kann.

Zumindest habe ich Anfänger keinen Plan, wie ich sonst mehrere Sachen in einer Datei speichern soll.
Lesabr muss die Datei nur fürs Programm sein, nicht für den User, im Gegenteil, ich wäre dankbar, wenn der User keine (oder nur erschwerte) Möglichkeiten hätte die Datei selber zu editieren, aber wie gesagt, ich Anfänger kann es bis jetzt nicht besser.
 
Hallo

Wozu sollen denn Trennzeichen gut sein, wenn das nicht als Text gespeichert werden muss ?

Solange die Grösse der Strukturen bekannt ist hat ein Computer sicher keine Probleme damit.
Am einfachsten wäre alles in eine Struktur zu packen und dann alles wie vorgeschlagen binär
zu lesen und zu schreiben. Bei mehreren Strukturen müsste man den Offset berechnen und
vor dem Lesen den Dateizeiger darauf positionieren - geht auch einfach.

VG
merano
 
"... geht auch einfach" gilt zumindest in diesem Fall nicht für einen Anfänger wie mich, denn wenn das so einfach wäre, hätte ich hier gar nicht erst fragen müssen.

Aber seis drum, ich bin ja dabei es zu lernen, also nehme ich mir auch die Zeit dafür und irgendwann begreife sogar ich wie es geht.
Dass ich beim speichern was verbessern kann, ok, habe ich begriffen, dass ich dann beim einlesen entsprechend was ändern muss ist mir auch klar, das krieg ich dann schon irgendwie hin.

Was mir im Moment noch nicht verständlich ist, wie mache ich beim Einlesen aus den Rohdaten wieder ein RECT oder LOGFONT?
Ich habe eine dumpfe Vorstellung von strcpy oder sowas, aber nicht mal einen Ansatz, wie das wirklich geht.
Mal angenommen, ich habe nur die 2 Sachen in der Datei, binär, wie vorgeschlagen, ohne Trennzeichen:

Code:
RECT rect;
GetWindowRect(hwnd,&rect);
LOGFONT lf;
HFONT MyFont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
GetObject(MyFont,sizeof(LOGFONT),&lf);

WriteFile(hFile,&rect ,sizeof(RECT),&dwWritten,0);
WriteFile(hFile,&lf,sizeof(LOGFONT),&dwWritten,0);

Dann mache ich beim Einlesen:

Code:
RECT rect;
LOGFONT lf;

// und weiter weiss ich nicht
 
Zurück