Arrays Pascal中的FileIO有问题
在我的编程入门课程中,我很难为最后一个项目创建一个有效的保存系统。我正试图保存一组狗的记录。每只狗都有一个名字、主人姓名、品种、性别(1和2与是和否相关)、绝育/绝育状态(1和2同样与是和否相关),以及一个存储在记录中的权重和BCS分数数组,所有这些都在整个狗数组的单独索引中绘制。我设置的系统完美地导入了一只狗,但一旦我添加另一只狗进入终端,我就会收到关于访问冲突的错误。我已经亲手执行了很多次,但似乎找不到问题所在。我将在下面附上代码。谢谢Arrays Pascal中的FileIO有问题,arrays,file-io,pascal,Arrays,File Io,Pascal,在我的编程入门课程中,我很难为最后一个项目创建一个有效的保存系统。我正试图保存一组狗的记录。每只狗都有一个名字、主人姓名、品种、性别(1和2与是和否相关)、绝育/绝育状态(1和2同样与是和否相关),以及一个存储在记录中的权重和BCS分数数组,所有这些都在整个狗数组的单独索引中绘制。我设置的系统完美地导入了一只狗,但一旦我添加另一只狗进入终端,我就会收到关于访问冲突的错误。我已经亲手执行了很多次,但似乎找不到问题所在。我将在下面附上代码。谢谢 type DogInformation = recor
type
DogInformation = record
OwnerName: String;
name: String;
breed: String;
gender: Integer;
weight: array of Integer;
spay_neut: Integer;
bcs: array of Integer;
end;
DogArray = array of DogInformation;
procedure SaveAllData(var dog: DogArray);
var
i, o, z: Integer;
StoredData: Text;
len: Integer;
begin
FileCreate('/Users/Nat/Desktop/data.txt');
AssignFile(StoredData, '/Users/Nat/Desktop/data.txt');
Reset(StoredData);
Rewrite(StoredData);
for i := 0 to (High(dog) - 1) do
begin
WriteLn(StoredData, '!');
WriteLn(StoredData, dog[i].name);
WriteLn(StoredData, '@');
WriteLn(StoredData, dog[i].OwnerName);
WriteLn(StoredData, '#');
WriteLn(StoredData, dog[i].breed);
WriteLn(StoredData, '$');
WriteLn(StoredData, dog[i].gender);
WriteLn(StoredData, '%');
WriteLn(StoredData, dog[i].spay_neut);
for o := 0 to High(dog[i].weight) do
begin
WriteLn(StoredData, '^');
WriteLn(StoredData, dog[i].weight[o]);
end;
for z := 0 to High(dog[i].bcs) do
begin
WriteLn(StoredData, '&');
WriteLn(StoredData, dog[i].bcs[z]);
end;
WriteLn(StoredData, '?');
end;
len := (Length(dog) - 1);
WriteLn(StoredData, '!');
WriteLn(StoredData, dog[len].name);
WriteLn(StoredData, '@');
WriteLn(StoredData, dog[len].OwnerName);
WriteLn(StoredData, '#');
WriteLn(StoredData, dog[len].breed);
WriteLn(StoredData, '$');
WriteLn(StoredData, dog[len].gender);
WriteLn(StoredData, '%');
WriteLn(StoredData, dog[len].spay_neut);
for o := 0 to High(dog[len].weight) do
begin
WriteLn(StoredData, '^');
WriteLn(StoredData, dog[len].weight[o]);
end;
for z := 0 to High(dog[len].bcs) do
begin
WriteLn(StoredData, '&');
WriteLn(StoredData, dog[len].bcs[z]);
end;
WriteLn(StoredData, '~');
Close(StoredData);
end;
procedure LoadAllData(var dog: DogArray);
var
ident: String;
i, o, z: Integer;
StoredData: Text;
skip: String;
begin
AssignFile(StoredData, '/Users/Nat/Desktop/data.txt');
Reset(StoredData);
i := 0;
o := 0;
z := 0;
SetLength(dog,1);
SetLength(dog[i].weight,0);
SetLength(dog[i].bcs,0);
repeat
begin
ReadLn(StoredData, ident);
if ident = '!' then
begin
WriteLn('Importing Dogs Name.......');
ReadLn(StoredData, dog[i].name);
WriteLn(dog[i].name);
end;
if ident = '?' then
begin
SetLength(dog, (Length(dog))+1);
i := i + 1;
end;
if ident = '@' then
begin
WriteLn('Importing Owner Name......');
ReadLn(StoredData, dog[i].OwnerName);
WriteLn(dog[i].OwnerName);
end;
if ident = '#' then
begin
WriteLn('Importing Breed...........');
ReadLn(StoredData, dog[i].breed);
WriteLn(dog[i].breed);
end;
if ident = '$' then
begin
WriteLn('Importing Gender..........');
ReadLn(StoredData, dog[i].gender);
WriteLn(dog[i].gender);
end;
if ident = '%' then
begin
WriteLn('Importing Spay/Neut.......');
ReadLn(StoredData, dog[i].spay_neut);
WriteLn(dog[i].spay_neut);
end;
if ident = '^' then
begin
WriteLn('Importing Weights.........');
SetLength(dog[i].weight, (Length(dog[i].weight))+1);
ReadLn(StoredData, (dog[i].weight[o]));
WriteLn(dog[i].weight[o], ' ');
o := o + 1;
end;
if ident = '&' then
begin
WriteLn('Importing BCS.............');
SetLength(dog[i].bcs, (Length(dog[i].bcs))+1);
ReadLn(StoredData, (dog[i].bcs[z]));
WriteLn(dog[i].bcs[z], ' ');
z := z + 1;
end;
end;
until ident = '~';
WriteLn('');
WriteLn('Import Complete...........');
Close(StoredData);
end;
任何信息或建议都会有帮助
谢谢,纳特
编辑-这是第二只狗在终端中的输出。除了狗的体重和BCS之外,所有内容都会显示出来,然后当我尝试通过添加一条新狗来编辑狗数组时,程序会以访问冲突为由退出
在循环的每次迭代中,您需要仔细地重新初始化加载过程中的变量:
i := 0;
repeat
o := 0;
z := 0;
SetLength(dog, i+1);
SetLength(dog[i].weight, 0);
SetLength(dog[i].bcs, 0);
...
inc(i);
until...
否则,
o
和z
变量将增加到高于权重和bcz数组上边界的值 我也决定写另一个答案。我已经给出了一个答案,说明了你问题的确切解决办法。但我觉得我需要解释一下,你使用的aproach从一开始就不是最优的。。。这不是帕斯卡方言的使用方式
让我们开始吧
首先。Pascal开发人员通常在用户定义类型的名称之前使用T
:我重命名了记录声明。这是申报单
type
TDogInformation = record
OwnerName: String;
// other fields...
end;
下一步。我声明了以下变量:
var
fl: file;
RecSize: word; // This variable will be used for fast data access
DI: array of TDogInformation;
i: word;
我以这种方式填充数据,您可以使用任何其他方式
Setlength(DI, 2);
with DI[0] do
begin
OwnerName := 'First owner';
name := 'First dog';
breed := 'Mixed';
gender := 0;
Setlength(weight, 2);
weight[0] := 56;
weight[1] := 60;
spay_neut := 1;
Setlength(bcs, 1);
bcs[0] := 15;
end;
with DI[1] do
begin
OwnerName := 'Second owner';
name := 'Second dog';
breed := 'Mixed mixed';
gender := 1;
Setlength(weight, 1);
weight[0] := 64;
spay_neut := 1;
Setlength(bcs, 12);
bcs[0] := 16;
bcs[1] := 18;
end;
现在我们可以快速写入数据。整个过程只需要几行代码
AssignFile(fl, 'b:\asd.txt');
ReWrite(fl);
for i := 0 to High(DI) do
begin
RecSize := SizeOf(DI[i]); //<--We calculate and keep the buffer size
BlockWrite(fl, RecSize, 2); //<--and write it in the file to simlify reading
BlockWrite(fl, DI[i], RecSize);//<--Now we write the record at once.
end;
CloseFile(fl);
就这些。您确实需要解析文本数据。最后。有一些技术允许一次写入整个集合(例如,使用TStream/TMemoryStream/TFileStream),而无需任何解析和/或设置/获取单个记录的长度。您是否进行过任何调试以缩小代码中导致访问冲突的部分?
AssignFile(fl, 'b:\asd.txt');
SetLength(DI, 0);//line is compulsory. We reinitialize DI
Reset(fl);
i := 0;
repeat
Setlength(DI, i+1);
BlockRead(fl, RecSize, SizeOf(RecSize) { =2 as it is a word });
//^ You will get the record size by reading the word variable first
BlockRead(fl, DI[i], RecSize); //Now read the record using its fetched size
WriteLn(DI[i].OwnerName);//output the records' data
Inc(i);
until Eof(fl);
CloseFile(fl);
ReadLn;