Delphi for循环和StringList错误 [英] Delphi for loops and StringList Errors

查看:210
本文介绍了Delphi for循环和StringList错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Ok guys, I've been trying to find out every possible mistake i'm making but I give up... I need help! What I'm writing is an app to manage rentals for my job and when the date is past, my app removes the name from 2 text files. I wrote 3 little functions(procedures) to make this work. Here:

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

This one loads from dates.dat file and remove the line containing the name of the employee.

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文件中删除了包含员工姓名的行.

This one removes the line containing the employee name from the perm.dat file.

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.

This one sticks those together. The isDue is a simple function that compares 2 dates and returns a TRUE if date is today or is past.

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错误.经过多次尝试,发现只有在员工的到期日是今天时才会发生这种情况.如果您需要更多信息,请发表评论! 在此先感谢您,我们将不胜感激!

The error I get is when it gets to remPerm in the updatePerms procedure.(*) I get a EStringList Error, out of bound (#). Figured out with many tries that it only happens when an employee's due date is today. Please comment if you need more info! Thanks in advance, any help is really appreciated!

推荐答案

问题是您正在使用for循环. for循环的终点仅在进入循环后才评估一次.那时您可能有100个项目,但是一旦您开始删除,项目就会减少.然后,这将导致列表索引超出范围错误.

The problem is that you are using a for loop. The end point of a for loop is only evaluated once when the loop is entered. At that point you may have 100 items, but once you start deleting there will be less. This will then result in a list index out of bounds error.

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

The simple fix is to reverse the for loop:

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

如果员工不止一次出现,这将起作用.

This will work if the employee occurs more than once.

但是,如果员工只出现一次,则可以使用break尽早退出循环:

However if the employee does only occur once, you can use break to exit from the loop early:

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循环.

Another solution is to use a while loop.

这篇关于Delphi for循环和StringList错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆