首先,我知道我会因使用过时的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'放在我搜索后甚至没有改变的地方。
答案 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;