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

Searching for an element in an array has no results?

首先,我知道我会因为使用过时的 Delphi 方法而被大喊大叫,但这是我被教导的方式,我只是为了即将到来的考试练习这些东西。

无论如何,我正在通过文本文件将一堆名称读取到数组中。然后,用户可以选择在文本文件中搜索名称,它会 return 该名称存在或不存在。

代码如下:

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

我做错了什么?

编辑:我放置 'LabelSearched' 的位置在我搜索后甚至没有改变。

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

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

通过研究 operator precedence 的 table 了解这一点。请注意 = 的优先级低于此表达式中的其他运算符。 notor 有更高的偏好,这就是我在 not Eof() 周围添加括号的原因。

因为 Eof returns False 这个测试总是失败并且永远不会进入 while 循环体。你是说

not Eof(myFile) or (bFound = False)

但是测试布尔值是否为真或假在惯用语上很差。所以我会这样做:

not Eof(myFile) or not bFound

即便如此,这仍然是错误的。您需要两个条件都为真才能进入新的迭代。如果 Eof returns 为真,进入循环体是不行的。所以你需要这个条件:

not Eof(myFile) and not bFound

我个人认为我会尝试不使用 bFound local 并使用 break 来摆脱循环,但这可能更像是个人品味的问题。

如果您想从旧版 Pascal I/O 继续前进,那么您可能会考虑 TStreamReader。这将允许您保持相同的 while 循环一次读取一行。

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

啊,是的,问题是:请查看您接受的对该问题的回答。

这不是您问题的直接答案,但您可以使用另一种方法 - 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;