数据结构(100分)

  • 主题发起人 主题发起人 SP229
  • 开始时间 开始时间
S

SP229

Unregistered / Unconfirmed
GUEST, unregistred user!
对这个一点不懂!
想定义一个结构,不知对不对?
type
TGsRec = packed record
Gs_Name: string[12];
LD: String[6];
ZS: integer;
GS_File: TStrings;
aDate: TDate;
end;

var
aDateF: file of TGsRec;
GsRec: TGsRec;
aFileName: string='D:/Gs.jjg';
procedure TForm1.Button6Click(Sender: TObject);
begin
AssignFile(aDateF,aFileName);
Rewrite(aDateF);
GsRec.Gs_Name:=edit1.Text;
GsRec.LD:='D';
GsRec.ZS:=15;
GsRec.GS_File:=memo2.Lines;
GsRec.aDate:=now;
Write(aDateF,GsRec);
CloseFile(aDateF);
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
AssignFile(aDateF,aFileName);
Reset(aDateF);
memo1.Clear;
seek(aDateF,strtoint(edit3.Text));
Read(aDateF,GsRec);
memo1.Lines.Add(GsRec.Gs_Name);
memo1.Lines.AddStrings(GsRec.GS_File);
CloseFile(aDateF);
end;

如果清除memo2中的内容,memo1中什么也没有,好象mwmo2中的内容并没有保存到文件中
如果要把memo2中的内容保存到文件中该如何做?
 
好像类型文件的结构里 不能有string、Tstrings、动态数组等,必须是有明确大小的类型。
 
你可以保存为两个文件,一个文件保存
Gs_Name: string[12];
LD: String[6];
ZS: integer;
aDate: TDate;
一个保存GS_File: TStrings;
 
那如果规定TStrings的大小呢?
 
Memo1.Lines.SaveToFile();
 
Memo1.Lines.SaveToFile();
这个我知道.
你看能否这样(我试过不行)
type
TGsRec = packed record
Gs_Name: string[12];
LD: String[6];
ZS: integer;
GS_File: TMemoryStream;//把TStrings改成TMemoryStream
aDate: TDate;
end;
我想把它保存到一个文件中,把TStrings转成其它类型也可以(把TStrings内容付值给它)
Memo2.Lines.SaveToStream();
 
今天可能等不到答案了,明天再来看,
是不是这个问题有点难?
 
你不能指望利用简单的记录文件读写的方法存放结构中的指针(所指向的)数据。Delphi
中的String(变长字符串)、TObject及其派生类型的对象实例等实际上都是指针,对于这
类信息,你用结构保存,只会保存指针的值,而不会保存指针所指向的内存区域内容。
如果内容是变长的,建议楼主用Stream来进行Read和Write——参考TComponent的流化存
取机制即可。
 
Creation-zy回答,是该是权威的回答
流和记录文件能否保存到一个文件中?
 
记录文件是专门用来读写定长数据单元的,流文件就灵活的多。一旦采用流,那么就不可
能再进行基于记录的读写(当然,如果需要,流也可以很容易的承担记录读写的任务)。文
件流的使用方法可以参考 2515070 号帖子。
除了FileStream之外,还可以简单的使用BlockRead/Write来实现不定长信息读写,请参
考 010625 号帖子。
 
to creation-zy
根据那两个贴,依样画弧,好象写入了,读不出什么东西,(那两贴最后也没解决问题)
type
a=packed record
id:string[6];
num:integer;
adr:array of integer;
//动态数组
end;

procedure TForm1.Button1Click(Sender: TObject);
var
FStr: TFileStream;
X: A;
i: integer;
begin
FStr:=TFileStream.Create('d:/abc.dat', fmCreate);
SetLength(x.adr, 5);
for I:=1 to Length(X.Adr)do
begin
x.adr[I-1]:=I*2;
FStr.Write(x.adr[I-1], sizeof(x));
end;

FStr.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
FStr: TFileStream;
X: A;
i: integer;
begin
FStr:=TFileStream.Create('d:/abc.dat', fmOpenRead);
FStr.Read(x, Sizeof(X));
SetLength(X.adr, Length(X.Adr));
for I:= 0 to Length(X.Adr)-1do
ShowMessage(IntToStr (x.adr) );
FStr.Free;
end;
 
仔细看看第一个帖子吧——你上面的代码尚未切入关键点。
定长部分的就不说了,我就说一下变长部分的读写流程:
变长信息是字符串的情况:
写入:
Stream.Write(VarLen,SizeOf(VarLen));
//先写长度
Stream.Write(VarStr[1],VarLen);
//再写内容——变量为字符串,应使用[1]
读取:
Stream.Read(VarLen,SizeOf(VarLen));
//读长度
SetLength(VarStr,VarLen);
//为变长字符串分配存储空间
Stream.Read(VarStr[1],VarLen);
//根据得到的长度读出内容
如果是变长数组:
写入:
Stream.Write(Length(MyArray),SizeOf(Integer));
//先写数组长度
for i:=0 to High(MyArray)do
Stream.Write(MyArray,SizeOf(MyArray));
//写入每个数组成员的内容
读取:
Stream.Read(AyLen,SizeOf(Integer));
//读长度
SetLength(MyArray,AyLen);
//为变长数组分配空间
for i:=0 to High(MyArray)do
Stream.Read(MyArray,SizeOf(MyArray));
//读出每个数组成员
 
明天好好看看,不懂再来问
 
to creation-zy
我搞不定(太笨了)
type
A=packed record
id:string[6];
num:integer;
adr:array of string;
//动态数组
end;
如果
A.ID:='005';
A.Num:=3;
SetLength(x.adr, memo1.Lines.Count-1);
for i:=0 to memo1.lines.count-1do
x.adr:=memo1.lines.strings;
我写好象是写进去了.但读的时候出错,在MEMO中只有两行,还有乱码.请老大帮我改改!
procedure TForm1.Button1Click(Sender: TObject);
var
FStr: TFileStream;
X: A;
i: integer;
begin
FStr:=TFileStream.Create('./abc.dat', fmCreate);
SetLength(x.adr, memo1.Lines.Count-1);
for I:=0 to high(x.adr)do
x.adr:=memo1.Lines.Strings;
FStr.Write(x,sizeof(integer));
for i := 0 to high(x.adr)do
FStr.Write(x.adr,sizeof(x.adr));
FStr.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
FStr: TFileStream;
X: A;
i: integer;
begin
FStr:=TFileStream.Create('./abc.dat', fmOpenRead);
FStr.Read(x.adr, Sizeof(integer));
SetLength(x.adr,sizeof(integer));
//为变长数组分配空间
for i:=0 to High(x.adr)do
fstr.Read(x.adr,SizeOf(x.adr));
//读出每个数组成员
SetLength(X.adr, Length(X.Adr));
for I:= 0 to high(X.Adr)do
memo2.Lines.Add(x.adr);
FStr.Free;
end;
 
type
RecA=packed record
id:string[6];
num:integer;
adr:array of string;
//动态数组
end;

procedure TForm1.Button1Click(Sender: TObject);
var
FStr: TFileStream;
X: RecA;
i,n: integer;
begin
X.ID:='005';
X.Num:=3;
SetLength(x.adr, memo1.Lines.Count);
for I:=0 to high(x.adr)do
x.adr:=memo1.Lines.Strings;
FStr:=TFileStream.Create('./abc.dat', fmCreate);
FStr.Write(X.ID,SizeOf(X.ID));
//直接写入记录中的定长字符串
FStr.Write(X.Num,SizeOf(X.Num));
n:=High(x.adr)+1;
//Element count of adr array
FStr.Write(n,sizeof(integer));
for i := 0 to high(x.adr)do
begin
n:=Length(x.adr);
FStr.Write(n,sizeof(Integer));
if Length(x.adr)>0 then
FStr.Write(x.adr[1],Length(x.adr));
end;
FStr.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
FStr: TFileStream;
X: RecA;
i,n: integer;
begin
FStr:=TFileStream.Create('./abc.dat', fmOpenRead);
FStr.Read(X.ID,SizeOf(X.ID));
FStr.Read(X.Num,SizeOf(X.Num));
FStr.Read(n,Sizeof(integer));
SetLength(x.adr,n);
//为变长数组分配空间
for i:=0 to High(x.adr)do
begin
FStr.Read(n,Sizeof(integer));
if n>0 then
begin
SetLength(x.adr,n);
fstr.Read(x.adr[1],n);
//读出每个数组成员
end;
end;
SetLength(X.adr, Length(X.Adr));
memo2.Lines.Clear;
for I:= 0 to high(X.Adr)do
memo2.Lines.Add(x.adr);
FStr.Free;
end;
 
多谢老大.
我要好好研究.给你加分
 
后退
顶部