Pascal:只显示一组数组而不显示文件中的其余部分

Pascal: Only displaying one set of array's and not the rest from file

所以我的代码只从我的文本文件中读取一组相册而拒绝读取文件中的其余部分。出于某种原因,为什么我让它读取专辑,它只显示文件包含“1”专辑而不是“2”。即使在我的循环中我已经将数组 SetLength 设置为等于 albumNumber 所以数组大小应该设置为当我开始我的 for 循环时的大小。

文本文件

2 (how many albums)
Adele (name)
Pop (genre)
2 (tracks)
Hello (Track 1)
ff (location)
Remedy (track 2)
dd (location)
Jcole
Rap
2
Toto
ff
Africa
dd

帕斯卡

type
    TrackRec = record
        name: String;
        location: String;
    end;
    GenreType = (Pop, Rap, Rock, Classic);
    AlbumRec = Record
        name: String;
        genre: GenreType;
        tracks: array of TrackRec;
    end;
type AlbumArray = array of AlbumRec; 
procedure ReadAlbum(var albums: AlbumArray; var myFile: TextFile);
var
    albumNumber, tracknumber, count, i: Integer;

begin
    AssignFile(myFile, 'mytestfile.dat');
    Reset(myFile);
    ReadLn(myFile, albumNumber);
    WriteLn('This file contained ', albumNumber, ' album/s');
    SetLength(albums, albumNumber); 

    for i := 0 to High(albums) do
    begin
        ReadLn(myFile, albums[i].name);
        ReadLn(myFile, albums[i].genre);
        ReadLn(myFile, tracknumber);
        SetLength(albums[i].tracks, tracknumber);
        for count := Low(albums[count].tracks) to tracknumber - 1 do
        begin
            ReadLn(myFile, albums[i].tracks[count].name);
            ReadLn(myFile, albums[i].tracks[count].location);
        end;
    end;
end;
procedure Main();
var
    i, count, select, change: Integer;
    albums: AlbumArray;
    myFile: TextFile;
    message: String;
begin

    WriteLn('Please select an option: ');
    WriteLn('-------------------------');
    WriteLn('1. Read Filename');
    WriteLn('2. Display Albums');
    WriteLn('3. Select an Album');
    WriteLn('4. Update an Album');
    WriteLn('5. Exit');
    WriteLn('-------------------------');
    repeat
        i := ReadInteger('Select option for menu:');
        case i of  
            1: ReadAlbum(albums, myFile);

            2: PrintAll(albums, myFile);

            3: PlayAlbum(albums, myFile);

            4: Update(albums, myFile);
        end;
    until i = 5;
end;

您的代码包含许多例程(例如 PlayAlbum) 没有包括来源。

无论如何,您可能会松一口气,因为您的 ReadAlbum 程序确实 可以正常工作,但也许您认为它不能正常工作而陷入混乱。

在下面,我已经解释了你如何调试它 以验证它是否有效。现在,用下面的代码替换你的 ReadAlbumMain, 其中还包括几个显示结果的过程。

完成后,编译并 运行 应用程序。

代码:

procedure ReadAlbum(var albums: AlbumArray; var myFile: TextFile);
var
    albumNumber, tracknumber, count, i: Integer;

begin
    AssignFile(myFile, 'D:\Delphi\Code\Lazarus\mytestfile.dat');
    Reset(myFile);
    ReadLn(myFile, albumNumber);
    WriteLn('This file contained ', albumNumber, ' album/s');
    WriteLn;  // To space out the display
    SetLength(albums, albumNumber);

    for i := 0 to High(albums) do
    begin
        ReadLn(myFile, albums[i].name);
        ReadLn(myFile, albums[i].genre);
        ReadLn(myFile, tracknumber);
        SetLength(albums[i].tracks, tracknumber);
        for count := Low(albums[count].tracks) to tracknumber - 1 do
        begin
            ReadLn(myFile, albums[i].tracks[count].name);
            ReadLn(myFile, albums[i].tracks[count].location);
        end;
    end;
end;

procedure PrintAlbum(Albums : AlbumArray; AlbumNumber : Integer);
var
  Tracks : Integer;
  Album : AlbumRec;
begin
  //  Note : This is incomplete, you should complete it yourself!
  //  I've used the local variable Album to avoid having to keep typing
  //  Albums[AlbumNumber] and because it makes inspection during debugging easier
  Album := Albums[AlbumNumber];
  WriteLn('Album number: ', AlbumNumber);
  Writeln('AlbumName: ', Album.Name);
  Writeln('AlbumGenre: ', Album.Genre);
  Writeln;  // to Space out the display;
end;

procedure PrintAlbums(Albums : AlbumArray);
var
  AlbumNumber : Integer;
  Album : AlbumRec;
begin
  for AlbumNumber := 0 to High(Albums) do begin
    Album := Albums[AlbumNumber];
    PrintAlbum(Albums, AlbumNumber);
  end;
end;

procedure Main();
var
  albums: AlbumArray;
  myFile: TextFile;
begin
   ReadAlbum(Albums, MyFile);
   PrintAlbums(Albums);
   WriteLn('Done');
   ReadLn;
end;

begin
  Main;
end.

下面介绍如何在免费软件Lazarus中开始调试 IDE 用于 FPC。

1 在 IDE 中打开您的项目,在行上设置调试器断点 for i := 0 to High(albums) 做 通过按 F5 或单击 "gutter" 中的蓝色圆圈 在编辑器的左侧 window。无论哪种方式,这条线都应该变成红色。

2 编译并 运行 应用程序。应该出现黑色控制台 window 然后调试器将停止在步骤 1 中设置的 BP。

3 按 Ctrl-F5。这将弹出一个 Watch Properties 对话框。 watch 是一种让调试器显示变量值的方法 随着程序的执行。进入 相册 在 Expression 框中。

如有必要,拖动观察列表 window 使其不与代码重叠 编辑器 window 或控制台 window.

4 现在,重复按F8 并仔细观察监视列表window。 F8 使调试器一次执行一行程序,称为 "single-stepping" for 显而易见的原因。请注意,监视列表 window 已经 "knows" 有 2 条专辑记录以及其中的字段。

当您单步执行 for i:=for count := 时,请注意字段 两条记录中的逐步填写

顺便说一句,Count 不是一个实际代表变量的好名字 讨厌 TrackNumber

5 最后,for i:= 循环将结束,此时您知道 Albums 数组已正确设置,包括第二个 Album 记录。

6 对调试器稍微熟悉一些后,您可以删除在步骤 1 中设置的 BP。相反,将 BP 放在 ReadAlbums 的最后一行。编译和 运行ning 应用程序后,它将停止在 BP 上,这样您就可以验证 Albums 的内容,而不必单步执行两个 for 循环的每一行。

7 现在,完成PrintAlbum的编码。如有必要,您可以按照步骤 1-6

进行调试

8 搜索在线 Lazarus 调试教程并阅读它们直到厌倦。

希望当您完成所有这些操作时,您会更好地了解需要哪些信息(包括代码)reader才能提供帮助。的关键 获得好的帮助是启用 reader 来重现问题,而你的 q 不会那样做。读者不必猜测缺少的代码应该做什么。即使很明显,问题实际上可能出在您未包含的代码中的某个地方,在这种情况下 readers 也无济于事。