在数组中搜索元素没有结果?
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 了解这一点。请注意 =
的优先级低于此表达式中的其他运算符。 not
比 or
有更高的偏好,这就是我在 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;
首先,我知道我会因为使用过时的 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 了解这一点。请注意 =
的优先级低于此表达式中的其他运算符。 not
比 or
有更高的偏好,这就是我在 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;