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'm trying to display the array I tried to create via a text file in a rich edit. But every time I run the app, it gives me an 'I/O error 6' error and nothing displays. I don't know if it's something with the text file or if it's something with the display procedure.
There are a few problems with your code, but regarding the I/O error specifically, error 6 means "invalid file handle".
Since you are getting a popup error notification, you clearly have I/O checking enabled, which it is by default.
I/O error 6 is not typical for a failure on System.Reset()
, and you are not seeing any other kind of error related to a failure in opening a file, so we can safely assume that the file is being opened successfully, and that System.Readln()
and System.CloseFile()
are not being passed an invalid I/O handle.
So that leaves just one line that could be receiving an invalid I/O handle:
while not EOF do
System.Eof()
has an optional parameter to tell it which file to check. Since you are omitting that parameter, Eof()
will use System.Input
instead. And a GUI process does not have a STDIN handle assigned by default. So that is likely where error 6 is coming from.
That line needs to be changed to this instead:
while not EOF(tSongFile) do
UPDATE: given the declaration of arrSongs
you have shown in comments (arrSongs: array[1..MAX] of string;
), there are additional problems with your code. You need to make sure the reading loop does not try to store more than MAX
strings in the array. Also, your reading loop is trying to store a string at index 0, which is not a valid index since the array starts at index 1. Also, Display()
is skipping the last string in the array. See what happens when you omit important details?
Try this instead:
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;
That being said, I would suggest getting rid of the reading loop completely. You can use a TStringList
instead:
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;
Or, you can use TFile.ReadAllLines()
instead:
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;