Joshua Nguyen
Joshua Nguyen

Reputation: 153

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

So my code only reads one set of albums from my textfile and refused to read the rest in the file. For some reason why I get it to read album, it only displays that the file contain "1" album instead of "2".Even though in my loop i've SetLength the array to equal the albumNumber so the array size should be set to that when i begin my for loop.

textfile

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

pascal

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;

Upvotes: 0

Views: 342

Answers (1)

MartynA
MartynA

Reputation: 30715

Your code includes a number of routines (e.g. PlayAlbum) for which you have not included the source.

Anyway, you may be relieved to know that in fact your ReadAlbum procedure does work correctly, but perhaps you have gotten into a muddle thinking that it does not.

Down below, I've explained how you could have debugged it to verify that it works. For now, replace your ReadAlbum and Main by the code below, which also includes a couple of procedures to display the results.

Once you've done that, compile and run the app.

Code:

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.

The following explains how to start debugging in the freeware Lazarus IDE for FPC.

1 With your project open in the IDE, set a debugger breakpoint on the line for i := 0 to High(albums) do by either pressing F5 or clicking the blue circle in the "gutter" on the left of the editor window. Either way, the line should turn red.

2 Compile and run the application. The black console window should appear and then the debugger will stop on the BP set in step 1.

3 Press Ctrl-F5. This will pop op a Watch Properties dialog. A watch is a way to get the debugger to display the value of a variable as the program executes. Enter Albums in the Expression box.

If necessary, drag the Watch List window so that it doesn't overlap the code editor window or the console window.

4 Now, repeatedly press F8 and observe the Watch List window carefully. F8 causes the debugger to execute the program a line at a time, called "single-stepping" for obvious reasons. Note that the Watch List window already "knows" that there are 2 Album records and what there fields are.

As you single step through the for i:= and for count :=, notice how the fields of the two records are progressively filled out.

Btw, Count is not a good name for a variable which actually rep resents the TrackNumber

5 Eventually, the for i:= loop will finish, and at the point you know that the Albums array is correctly set up, including the second Album record.

6 Once you're a bit more familiar with the debugger, you could delete the BP you set in step 1. Instead, place a BP on the final line of ReadAlbums. After compiling and running the application, it will stop on the BP so that you can verify Albums's content without having to single-step each line of the two for loops.

7 Now, complete the coding of PrintAlbum. If necessary you can debug it as per steps 1-6

8 Search for online Lazarus debugging tutorials and read them until it gets boring.

Hopefully, by the time you've done all this, you'll have a better idea what information (including code) readers need to have in order to help. The key to getting good help is to enable the reader to reproduce the problem, and your q doesn't do that. Readers shouldn't have to guess what missing code is supposed to do. Even if it is obvious, the problem may actually turn out to be somewhere in the code you haven't included, in which case readers can't help anyway.

Upvotes: 1

Related Questions