gpt4 book ai didi

Delphi for 循环和 StringList 错误

转载 作者:行者123 更新时间:2023-12-03 18:01:01 26 4
gpt4 key购买 nike

好的伙计们,我一直在努力找出我可能犯的每一个错误,但我放弃了……我需要帮助!我正在写的是一个应用程序来管理我的工作租金,当日期过去时,我的应用程序会从 2 个文本文件中删除名称。我写了 3 个小函数(过程)来完成这项工作。这里:

这个从 dates.dat 文件加载并删除包含员工姓名的行。

procedure remDate(emp: String);/// Removes employee from date file
var
pos1, i: integer;
dateList: TStringList;
begin
dateList:=TStringList.Create;
dateList.LoadFromFile('Data\dates.dat');
for i:=0 to dateList.Count-1 do begin
pos1:=AnsiPos(emp, dateList[i]);
if pos1<>0 then begin
dateList.Delete(i);
dateList.SaveToFile('Data\dates.dat');
end;
end;
dateList.Free;
end; //eo remDate

这会从 perm.dat 文件中删除包含员工姓名的行。

procedure remPerm(emp: String);/// Removes employee from perm file
var
pos1, i: integer;
permList: TStringList;
begin
permList:=TStringList.Create;
permList.LoadFromFile('Data\perm.dat');
for i:=0 to permList.Count-1 do begin
pos1:=AnsiPos(emp, permList[i]);
if pos1<>0 then begin
permList.Delete(i);
permList.SaveToFile('Data\perm.dat');
end;
end;
permList.Free;
end; //eo remPerm

这个把那些粘在一起。 isDue 是一个简单的函数,它比较 2 个日期,如果日期是今天或过去,则返回 TRUE。

procedure updatePerms;
var
empList: TStringList;
i: integer;
begin
empList:=TStringList.Create;
empList.LoadFromFile('Data\employes.dat');
for i:=0 to empList.Count-1 do begin
if isDue(empList[i]) then begin
remDate(empList[i]);
remPerm(empList[i]); (*) Here is where the error points.
end;
end;
empList.Free;
end;

我得到的错误是当它在 updatePerms 过程中到达 remPerm 时。(*)我收到 EStringList 错误,超出范围 (#)。通过多次尝试发现,只有当员工的截止日期是今天时才会发生这种情况。如果您需要更多信息,请发表评论!在此先感谢,非常感谢任何帮助!

最佳答案

问题是您正在使用 for 循环。 for 循环的终点仅在进入循环时计算一次。那时你可能有 100 个项目,但一旦你开始删除,就会更少。这将导致列表索引越界错误。

简单的解决方法是反转 for 循环:

procedure remDate(emp: String);
/// Removes employee from date file
var
pos1, i: integer;
dateList: TStringList;
begin
dateList := TStringList.Create;
dateList.LoadFromFile('Data\dates.dat');
for i := dateList.Count - 1 downto 0 do
begin
pos1 := AnsiPos(emp, dateList[i]);
if pos1 <> 0 then
begin
dateList.Delete(i);
dateList.SaveToFile('Data\dates.dat');
end;
end;
dateList.Free;
end; // eo remDate

如果员工多次出现,这将起作用。

但是,如果员工只出现一次,您可以使用 break 提前退出循环:

procedure remDate(emp: String);
/// Removes employee from date file
var
pos1, i: integer;
dateList: TStringList;
begin
dateList := TStringList.Create;
dateList.LoadFromFile('Data\dates.dat');
for i := 0 to dateList.Count - 1 do
begin
pos1 := AnsiPos(emp, dateList[i]);
if pos1 <> 0 then
begin
dateList.Delete(i);
dateList.SaveToFile('Data\dates.dat');
Break; // <-- early exit
end;
end;
dateList.Free;
end; // eo remDate

另一种解决方案是使用 while 循环。

关于Delphi for 循环和 StringList 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8222019/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com