Pascal中的无限循环,怎么来的?

时间:2011-05-08 02:11:36

标签: loops inno-setup freepascal

我写了一个Pascal函数来替换文件中的整行或者只是其中的一部分,以便在Inno Setup中使用:

function ReplaceInFile(const FilePath, OldLinePart, Replacement: String;
                       DoReplaceWholeLine, IsCaseSensitive: Boolean): Boolean;
var
  FileLines:          TArrayOfString;
  Index:              Integer;
  FoundAtPos:         Integer;
  LeftOfOldLinePart:  String;
  RightOfOldLinePart: String;
  IsReplaced:         Boolean;
begin
  Result := False;
  if FileExists(FilePath) then begin
    LoadStringsFromFile(FilePath, FileLines);
    for Index := 0 to GetArrayLength(FileLines) - 1 do
    begin
      repeat
        FoundAtPos := 0;
        if IsCaseSensitive then
          FoundAtPos := Pos(OldLinePart, FileLines[Index])
        else
          FoundAtPos := Pos(Uppercase(OldLinePart), Uppercase(FileLines[Index]));
        if FoundAtPos > 0 then begin
          if DoReplaceWholeLine then begin
            FileLines[Index] := Replacement;
            IsReplaced := True;
          end
          else begin
            LeftOfOldLinePart := Copy(FileLines[Index], 1, FoundAtPos - 1);
            RightOfOldLinePart := Copy(FileLines[Index], FoundAtPos 
              + Length(OldLinePart), Length(FileLines[Index]) 
              - Length(LeftOfOldLinePart + OldLinePart));
            FileLines[Index] := LeftOfOldLinePart + Replacement + RightOfOldLinePart;
            IsReplaced := True;
          end;
        end;
      until FoundAtPos = 0;
    end;
    if IsReplaced then
      if SaveStringsToFile(FilePath, FileLines, False) then
        Result := True;
  end;
end;

它曾经工作得很好,但只替换了FilePath指定的文件的每一行上第一次出现的OldLinePart,并替换了。那是我添加重复循环的时候。逻辑是Pos()在没有找到更多事件时返回0。然后它应该继续到下一行。然而事实是,循环一直在无限进行,我不知道为什么。我尝试在Break的{​​{1}}条款中添加else语句,但没有运气......

编辑:显然已经很晚了。我用一个很长的字符串替换了OldLinePart ......它包含了相同的单词。

问题已解决如下。

if FoundAtPos > 0

2 个答案:

答案 0 :(得分:2)

我只需拨打一次StringReplace即可取代您的循环。这可以防止(无限)循环并解决问题 请注意,您IsReplaced也遇到问题,例如FileLines[4]已被替换,但FilesLine[last]未被SaveStringsToFile替换,您的代码将不会调用uses SysUtils; function ReplaceInFile(const FilePath, OldLinePart, Replacement: String; DoReplaceWholeLine, IsCaseSensitive: Boolean): Boolean; var FileLines: TArrayOfString; Index: Integer; TempStr: String; IsReplaced: Boolean; Flags: TReplaceFlags; IsReplacedAnywhere: Boolean; begin Result := False; if FileExists(FilePath) then begin LoadStringsFromFile(FilePath, FileLines); IsReplacedAnywhere:= false; for Index := 0 to GetArrayLength(FileLines) - 1 do begin if DoReplaceWholeLine then begin IsReplaced := IsCaseSensitive and (Pos(OldLinePart, FileLines[Index]) > 0) or not(IsCaseSensitive) and (Pos(Uppercase(OldLinePart), Uppercase(FileLines[Index])) > 0); if IsReplaced then FileLines[Index] := Replacement; end else begin Flags:= [rfReplaceAll]; if not(IsCaseSensitive) then Flags:= Flags + [rfIgnoreCase]; TempStr:= StringReplace(FileLines[Index], OldLinePart, Replacement ,Flags); IsReplaced := (TempStr <> FileLines[Index]); if IsReplaced then FileLines[Index]:= TempStr; end; {else} IsReplacedAnywhere:= IsReplacedAnywhere or IsReplaced; end; {for Index} Result:= IsReplacedAnywhere and SaveStringsToFile(FilePath, FileLines, False); end; {if} end; 它也稍微简化了代码。

{{1}}

请告诉我这是否适合您。

答案 1 :(得分:0)

现在应该使用StringChangeEx完成。很高兴它支持Unicode。通过删除旧功能打破旧脚本的方式并不好。 StringReplace不再编译;即使这是Delphi的功能。 StringChange已被弃用。