Discussion:
How to Load/Save a TList
(too old to reply)
p***@yahoo.com
2008-09-05 00:12:38 UTC
Permalink
I need to figure out some way to save/load the content of a TList to/
from a file.
Is there some easy way to do that ?
I know that the strems-classes has a WiteContents method. Is that the
way to go ? I mean to start by serializing the TList somehow ? How
would that be done in that case ?
Any advice apreciated!
John Kettle
2008-09-05 09:54:26 UTC
Permalink
In message
Post by p***@yahoo.com
I need to figure out some way to save/load the content of a TList to/
from a file.
Is there some easy way to do that ?
I know that the strems-classes has a WiteContents method. Is that the
way to go ? I mean to start by serializing the TList somehow ? How
would that be done in that case ?
Any advice apreciated!
TList holds an array of pointers that can dynamically grow or shrink as
you add items to the list of objects to which it refers. Do you want to
load/save just the pointers or the items they are pointing to too? Tell
me a bit more about what has to be achieved.
JK
--
John Kettle
p***@yahoo.com
2008-09-05 11:15:14 UTC
Permalink
Post by John Kettle
In message
Post by p***@yahoo.com
from a file.
Is there some easy way to do that ?
I know that the strems-classes has a WiteContents method. Is that the
way to go ? I mean to start by serializing the TList somehow ? How
would that be done in that case ?
Any advice apreciated!
TList holds an array of pointers that can dynamically grow or shrink as
you add items to the list of objects to which it refers. Do you want to
load/save just the pointers or the items they are pointing to too? Tell
me a bit more about what has to be achieved.
JK
--
John Kettle
Hi John and thanks for your reply !
Now when I think about it I realize that it would be meaningless to
save the pointers.
My scenario is that I use a TList object as a convenient way to store
information during a session but I would also like to make it survive
beyound the session, i.e save the data (that the pointers point to) to
disk.
I realize now that Load/Save would be impossible to implement for the
designers of TList when they dont know what is stored.
I suppose one way to do it would be to derive a new class from TList
that actually knows whats stored. In my case that would be 6 new
classes since I have 6 different TList-s that I need to store.

I guess what I'm really after is some smart way to approach the
problem, I suspect that lots of people have had this problem before
me, so there might be

The only things that the list elements contains are ints and strings
so it would be easy to use TStringList (that has Load/Save) but then
how do I separate the records?
Lets say the definition of one list element is
typedef struct Settings
{
string name;
int BP;
int WP;
} TSettings;
Maybee there's some smart "pattern" or "template" ?
John Kettle
2008-09-05 22:25:07 UTC
Permalink
I have created a demo form with finish, save, load, add, and show
buttons and four edit boxes Edit1 through Edit4
Here is the code pasted from my main (and only) form to do what I think
you want. Depending on what version CB you are running you can update
my old stdio.h type commands to newer <iostream.h> type commands ( or
get back to me for translation) but this should give the gist of what's
needed. . No error checking in code so save you working out from
listing. put name in edit1 ints in 2 and 3 click add repeat etc put
value 0 to max entries-1 in edit4 click show . save before load

#include <vcl.h>
#pragma hdrstop
#include "main.h"
#include <string.h> //
//#include <iostream> //
#include <stdio.h>
#include <dstring.h>// iostream must be before dstream to use stream
operators
#include <dir.h> // on AnsiStrings
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//I have set up following globally (ugh!) you can place as appropriate
to your app
//****************************************************************
#define MAXFILEPATH 100
typedef struct
{
char name[50];
int BP;
int WP;
}TSettings;
typedef TSettings* LPointer;
LPointer TheStorageStructure;
TList *DemoList = new TList;
//*****************************************************************

//-----------------------------------------------------------------------
----
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//-----------------------------------------------------------------------
----
void __fastcall TMainForm::finishClick(TObject *Sender)
{
for(int n=0; n<DemoList->Count; n++)
{
TheStorageStructure = (LPointer) DemoList->Items[n];
delete TheStorageStructure;
}
delete DemoList;
Application->Terminate();
}
//-----------------------------------------------------------------------
----
void __fastcall TMainForm::saveClick(TObject *Sender)
{
//save the structure data
AnsiString FilerRoot, FileName; // FilerRoot to hold current working
directory - cwd
int n=0; // index of structure being
processed
FILE* fh=0; // fh var to hold file handle,
char ThisPath[MAXFILEPATH]; // buffer for getcwd()
getcwd(ThisPath,MAXFILEPATH); // in dir.h
FilerRoot=ThisPath;
FileName=FilerRoot+"\\tlistdemo.jke"; // use whatever file extension
you feel appropriate
n=-1;
try
{
fh=fopen(FileName.c_str(),"w+b"); // create empty file for update
binary
while(n<((DemoList->Count)-1)) // < also w-1 as count is
number of items 1 2 3 etc but array zero
// indexed and n incremented
inside loop
{
n++;
TheStorageStructure = (LPointer) DemoList->Items[n];
fseek(fh,(long)(sizeof(TSettings)*n),SEEK_SET);
fwrite(TheStorageStructure,sizeof(TSettings),1,fh);
}
fclose(fh);
}
catch(...)
{
fcloseall();
}
}

//-----------------------------------------------------------------------
----
void __fastcall TMainForm::loadClick(TObject *Sender)
{
//reload the structure data
AnsiString FilerRoot, FileName; //FilerRoot to hold current working
directory - cwd
FILE* fh=0; // fh var to hold file handle,
int n=0;
char ThisPath[MAXFILEPATH];
getcwd(ThisPath,MAXFILEPATH);
FilerRoot=ThisPath;
FileName=FilerRoot+"\\tlistdemo.jke";
n=-1;
try
{
fh=fopen(FileName.c_str(),"r+b"); // re-open empty file for read
write random access
while(feof(fh)==0)
{
n++;
TheStorageStructure = new TSettings;
fseek(fh,(long)(sizeof(TSettings)*n),SEEK_SET);
fread(TheStorageStructure,sizeof(TSettings),1,fh);
DemoList->Add(TheStorageStructure);
}
fclose(fh);

}
catch(...)
{
fcloseall();
}
}
//-----------------------------------------------------------------------
----
void __fastcall TMainForm::addClick(TObject *Sender)
{
//add some data into a 'structure unit'
TheStorageStructure = new TSettings;
strcpy(TheStorageStructure->name,Edit1->Text.c_str());
TheStorageStructure->BP=atoi(Edit2->Text.c_str());
TheStorageStructure->WP=atoi(Edit3->Text.c_str());
DemoList->Add(TheStorageStructure);
Edit4->Text=DemoList->Count; //display current item count added
}
//-----------------------------------------------------------------------
----
void __fastcall TMainForm::showClick(TObject *Sender)
{
//show an item - type required index in Edit4 remember to count
from zero - no error checking!
TheStorageStructure = (LPointer)
DemoList->Items[atoi(Edit4->Text.c_str())];
Edit1->Text= TheStorageStructure->name;
Edit2->Text= TheStorageStructure->BP;
Edit3->Text= TheStorageStructure->WP;
}
--
John Kettle
John Kettle
2008-09-05 22:54:21 UTC
Permalink
using fstream.h becomes


void __fastcall TMainForm::saveClick(TObject *Sender)
{
//save the structure data
AnsiString FilerRoot, FileName; // FilerRoot to hold current working
directory - cwd
int n=0; // index of structure being
processed
char ThisPath[MAXFILEPATH]; // buffer for getcwd()
getcwd(ThisPath,MAXFILEPATH); // in dir.h
FilerRoot=ThisPath;
FileName=FilerRoot+"\\tlistdemo.jke"; // use whatever file extension
you feel appropriate
n=-1;
ofstream outfile(FileName.c_str(), ios::trunc | ios::binary); // open
new binary file
while(n<((DemoList->Count)-1))
{
n++;
TheStorageStructure = (LPointer) DemoList->Items[n];
outfile.write((char*)TheStorageStructure, sizeof(TSettings));
}
outfile.close();
}

//-----------------------------------------------------------------------
----
void __fastcall TMainForm::loadClick(TObject *Sender)
{
//reload the structure data
AnsiString FilerRoot, FileName; //FilerRoot to hold current working
directory - cwd
int n=0;
char ThisPath[MAXFILEPATH];
getcwd(ThisPath,MAXFILEPATH);
FilerRoot=ThisPath;
FileName=FilerRoot+"\\tlistdemo.jke";
n=-1;
ifstream infile(FileName.c_str(), ios::binary);
while(infile)
{
n++;
TheStorageStructure = new TSettings;
infile.read((char*)TheStorageStructure,sizeof(TSettings));
DemoList->Add(TheStorageStructure);
}
infile.close();
}

regards JK
--
John Kettle
Loading...