procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 1 to iCount-1 do
begin
redOutput.Lines.Add(IntToStr(i)+arrSongs[i]);
end;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
var
tSongList: TextFile;
sSong: string;
begin
iCount := 0;
AssignFile(tSongList, ExtractFilePath(Application.ExeName)+'Songs.txt');
Reset(tSongList);
while not EOF do
begin
Readln(tSongList, sSong);
arrSongs[iCount] := sSong;
Inc(iCount);
end;
CloseFile(tSongList);
Display;
end;
我正在尝试通过富文本编辑显示通过文本文件创建的数组。但是,每次我运行该应用程序时,都会显示“ I / O错误6”错误,并且没有任何显示。我不知道这与文本文件有关,还是与显示过程有关。
答案 0 :(得分:5)
您的代码有一些问题,但是关于I / O错误,错误6表示“无效的文件句柄”。
由于收到弹出错误通知,因此您显然已启用I/O checking,这是默认设置。
I / O错误6并不是System.Reset()
上失败的典型代表,并且您没有看到与打开文件失败有关的任何其他类型的错误,因此我们可以放心地假设该文件正在已成功打开,并且没有向System.Readln()
和System.CloseFile()
传递无效的I / O句柄。
所以只剩下一行可能接收到无效的I / O句柄:
while not EOF do
System.Eof()
有一个可选参数来告诉它要检查哪个文件。由于您省略了该参数,因此Eof()
将使用System.Input
。并且GUI进程没有默认分配的STDIN句柄。所以这很可能是错误6的来源。
该行需要改为:
while not EOF(tSongFile) do
更新:鉴于已在注释(arrSongs
)中显示了arrSongs: array[1..MAX] of string;
的声明,因此代码还有其他问题。您需要确保读取循环不会尝试在数组中存储超过MAX
个字符串。另外,您的读取循环正在尝试将一个字符串存储在索引0处,该索引不是有效的索引,因为该数组从索引1开始。而且,Display()
跳过了字符串中的 last 字符串。数组。看到省略重要细节会发生什么?
尝试以下方法:
private
arrSongs: array[1..MAX] of string;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 1 to iCount do
begin
redOutput.Lines.Add(IntToStr(i) + arrSongs[i]);
end;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
var
tSongList: TextFile;
sSong: string;
begin
iCount := 0;
AssignFile(tSongList, ExtractFilePath(Application.ExeName) + 'Songs.txt');
Reset(tSongList);
try
while (not EOF(tSongList)) and (iCount < MAX) do
begin
Readln(tSongList, sSong);
arrSongs[1+iCount] := sSong;
Inc(iCount);
end;
finally
CloseFile(tSongList);
end;
Display;
end;
话虽如此,我建议您完全摆脱阅读循环。您可以改用TStringList
:
uses
..., System.Classes;
...
private
lstSongs: TStringList;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 0 to lstSongs.Count-1 do
begin
redOutput.Lines.Add(IntToStr(i+1) + lstSongs[i]);
end;
end;
procedure TfrmSongs.FormCreate(Sender: TObject);
begin
lstSongs := TStringList.Create;
end;
procedure TfrmSongs.FormDestroy(Sender: TObject);
begin
lstSongs.Free;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
begin
lstSongs.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Songs.txt');
Display;
end;
或者,您可以改用TFile.ReadAllLines()
:
uses
..., System.IOUtils;
...
private
arrSongs: TStringDynArray;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 0 to High(arrSongs) do
begin
redOutput.Lines.Add(IntToStr(i+1) + arrSongs[i]);
end;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
begin
arrSongs := TFile.ReadAllLines(ExtractFilePath(Application.ExeName) + 'Songs.txt');
Display;
end;