在数组中搜索元素没有结果?

时间:2015-02-11 07:34:40

标签: delphi

首先,我知道我会因使用过时的Delphi方法而大喊大叫,但这是我教授的方式,而我只是在考试时练习这些东西。

无论如何,我通过文本文件将一堆名称读入数组。然后,用户可以选择在文本文件中搜索名称,它将返回名称在那里,或者不是。

以下是代码:

procedure TForm1.btnSearchClick(Sender: TObject);
var
  myFile : TextFile;
  Search : string;
  k : Integer;
  arrNames : array [1..200] of string;
  bFound : Boolean;
begin
  AssignFile (myFile, 'names.txt');

  reset(myFile);

  Search := UpperCase(InputBox('Search a Name', '', 'Tiffani Bressler'));

  k := 1;

  bFound := False;

  while not Eof(myFile) or bFound = False do begin

      Readln(myFile, arrNames[k]);

      if Search = UpperCase(arrNames[k]) then

      begin

        bFound := true;

      end;

      lblLineSearched.Caption := 'Line searched: ' + IntToStr(k);

      inc(k);

    end;

    if bFound = True then

      ShowMessage('You searched for: ' + Search + ' and it was found on line: ' + IntToStr(k))

      else ShowMessage('You searched for: ' + Search + ' and it was not found');

  CloseFile(myFile);

end; 

问题是,只要我按下搜索按钮(我直接从文本文件中复制一个名称),我就会收到Name not found的消息。

我做错了什么?

编辑:我把#Se; LabelSearched'放在我搜索后甚至没有改变的地方。

2 个答案:

答案 0 :(得分:6)

逻辑表达式错误。相等测试绑定到整个表达式。它与

相同
((not Eof(myFile)) or bFound) = False

通过研究operator precedence的表来了解这一点。请注意,=的优先级低于此表达式中的其他运算符。并且not的偏好高于or,这就是为什么我在not Eof()附近添加了parens。

由于Eof返回False,此测试始终失败,并且永远不会输入while循环的正文。你的意思是

not Eof(myFile) or (bFound = False)

但是,根据真假来测试布尔值是不合适的。所以我会这样做:

not Eof(myFile) or not bFound

即便如此,这仍然是错误的。您需要两个条件才能输入新的迭代。如果Eof返回true,那么进入循环体是没有用的。所以你需要这个条件:

not Eof(myFile) and not bFound

我个人认为我会尝试在没有bFound本地的情况下使用break来逃避循环,但这可能更多的是个人品味。

如果您想继续使用传统的Pascal I / O,那么您可以考虑TStreamReader。这将允许您保持相同的while循环一次读取一行。

我确信我之前已经说过了,很可能是你,但是你的阵列不仅毫无意义而且浪费,而且很危险。你一次考虑一行。使用相同的string局部变量来读取每一行。就目前而言,您的代码是缓冲区溢出错误的诱饵。

啊,是的,这是问题所在:Access of violation at address 00404094 with AssignFile();请查看您接受的答案。

答案 1 :(得分:4)

这不是您问题的直接答案,但您可以使用其他方法 - TStringList

类似的东西:

procedure Search(const aFileName: String; const aSearchString: String);
var
  index: Integer;
  sl: TStringList;    
begin
  sl := TStringList.Create;
  try        
    sl.LoadFromFile(aFileName);

    // case sensitive search
    sl.CaseSensitive := True;

    index := sl.IndexOf(aSearchString);

    if index > -1 then
      ShowMessage(Format('String found at line %d', [index + 1])) else
      ShowMessage('String not found!');

  finally
    sl.Free;
  end;
end;