如何将不定长的数组加入到一个记录结构中去?(100分)

G

gxh

Unregistered / Unconfirmed
GUEST, unregistred user!
记录Tmyrecord中包含一个数组用来记录Tpoint型的数组,但数组长度是
不确定的,如何定义此记录结构?
如果将基于此记录结构的一组对象保存到一个文件中去,是使用file of
Tmyrecord 还是使用流操作比较合适?
望能举例加以诠释.
 
试一试下面的代码:
type
PPoint = ^TPoint;
MyRecord = record
ID : string[10];
PointList : TList; //可以是动态的
end;
...

procedure TForm1.FormCreate(Sender : TObject)
begin
Rec.PointList := TList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
I : integer;
PP : PPoint;
begin
Randomize;
for I := 0 to 1000 do begin
New(PP);
PP.X := Random(800);
PP.Y := Random(600);
Rec.PointList.Add(PP);
end;
with Form1.Canvas do begin
for I := 0 to Rec.PointList.Count - 1 do begin
Ellipse(PPoint(Rec.PointList.Items).X-3,
PPoint(Rec.PointList.Items).Y-3,
PPoint(Rec.PointList.Items).X+3,
PPoint(Rec.PointList.Items).Y+3
);
end;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
I : integer;
begin
for I := 0 to Rec.PointList.Count - 1 do begin
Dispose(PPoint(Rec.PointList.Items));
end;
end;
 
对不起,忘了在FormDestroy()中添加
  Rec.PointList.Free;
 
用链表可以解决动态生长的点组数,但作为一个对象要写到文件中去必须是实际的
坐标值,单独用流保存点组是比较简单的,用文件流就可以保存,这个方法我已实现.
如果用file of myrecord形式进行保存,就可以比较容易的定位和进行增删、
修改等操作。关键在于以此形式保存时,其域必须是实际的坐标值而不是链表指针,
如何将此两者结合起来并作为一个完整的对象进行操作才是问题的关键,希望有
高人指点。
另外用文件和流进行此类型对象操作的比较和实例希望能提供。谢谢。
 
我们一般情况下是使用 File 类型和 Blockwrite, Blockread 操作。

pXYS: ^arrar[0..4095] of Tpoint;
TMyRecord = record
ID: string[10];
pointNum: integer;
xys: PXYS;
end;

var ff: file;
MyRecord: TMyRecord;

begin

//写数据
assign(ff, 'Test.dat'); rewrite(ff);
blockwrite(ff, MyRecord, sizeof(MyRecord));
blockwrite(ff, MyRecord.PXYS^, sizeof(TPoint)*MyRecord.PointNum);

//读数据
assign(ff, 'Test.dat'); reset(ff);
blockread(ff, MyRecord, sizeof(MyRecord));
GetMem(MyRecord.PXYS, sizeof(TPoint)*MyRecord.PointNum)
blockread(ff, MyRecord.PXYS^, sizeof(TPoint)*MyRecord.PointNum);

end;

使用 TStream 的方法想来类似,它有类似的Read 和 Write.但没有正式用过。
对您的实际问题,我还是不够理解,如有进一步要求,请再说明。
 

前几天我也想到了一个解决方法,
1.写文件:将记录对象集和点组集分别存为两个文件
recfile:file of Tmyrecord; //对象集文件
pointfile:file of Tpoint;//点集文件
2. 读文件:通过读对象集中的PointNum,然后在点组集中读取
PointNum*sizeof(Tpoint)大小的数据保存在pointarray数组中。
记录的定位还是要在recfile中读取ID、PointNum等数据,然后在
点组集文件中进行增删等编辑工作。

yysun提供的方法可以解决点组的存储问题。但我的本意是将Tmyrecord
和点组集pointarray集成为一个对象,如果不行的话变通一下,将Tmyrecord
和点组集依次交替保存到一个文件中去,读点集数据和记录定位方法与刚才我用
两个文件保存数据的方法类似。
希望你能对我的这个方法提出一些看法。因为delphi是不允许在记录中
包含不能确定长度大小的记录域的,我想知道您是否有办法将Tmyrecord
和点组集pointarray集成为一个记录对象。
谢谢。


 
hi, gxh,

我给您的前一个解释中已经可以将TMyRecord和点数组保存在一个文件中了.
好象 Arc View 的 *.shp 也是用类似的方法.




 
可以考虑将point array写成一个class,如果你不喜欢指针的话可以使用动态数组,
但是保存/读文件必须自己写一段 TReader 和 TWriter 程序,Delphi现存的
Stream read/write 是绝对不能满足你的要求的。
 
顶部 底部