Recent

Author Topic: Usage of append  (Read 3488 times)

TheGeNi

  • Newbie
  • Posts: 2
Usage of append
« on: February 16, 2019, 03:11:57 pm »
Hey,

I have to write a little program for my course. It's supposed to be a quiz and I have to save all results of all users into a file. I need to use that file later to get the results into a string grid.

This is what I did to do that:

Code: Pascal  [Select][+][-]
  1.  
  2. interface
  3.  
  4. uses
  5.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, u_variables,
  6.   FileUtil, ExtCtrls, LCLType;
  7.  
  8. [...]
  9.  
  10. implementation
  11.  
  12. type BStruktur = record
  13.      sname        : string[30];
  14.      gscore        : integer;
  15. end;
  16.  
  17. var
  18.   board       : file of BStruktur;
  19.   boardsatz : BStruktur;
  20.  
  21.  
  22. [...]
  23.  
  24. procedure TF_quiz.B_StartClick(Sender: TObject);
  25. begin
  26.  
  27.     assignfile(board,'board.db');
  28.     append(board);
  29.     boardsatz.sname := sname;
  30.     boardsatz.gscore := gscore;
  31.     Write(board,boardsatz);
  32.     closefile(board);
  33.  
  34. end;
  35.  
  36.  

When I try to start this, I get this error message:

Quote
u_quiz.pas(236,21) Error: Call by var for arg no. 1 has to match exactly: Got "File Of BStruktur" expected "Text"

I don't really understand how append works and can't find anything that is helping about it online or in my scripts.


Thanks a lot for helping!

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Usage of append
« Reply #1 on: February 16, 2019, 03:49:05 pm »
Append() only works for files of type Text (or it's synonym TextFile).
If the file already exists use Reset(), otherwise create it with Rewrite().
After Reset() uses seek() to go to the position in the file you want to be.

Bart

Thaddy

  • Hero Member
  • *****
  • Posts: 14165
  • Probably until I exterminate Putin.
Re: Usage of append
« Reply #2 on: February 16, 2019, 03:58:00 pm »
Append() only works for files of type Text (or it's synonym TextFile).
@Bart
That's not true Bart. It works for any typed file. Always has. Note that e.g. a file of a record type needs packed records. That is the only limitation.
Specialize a type, not a var.

TheGeNi

  • Newbie
  • Posts: 2
Re: Usage of append
« Reply #3 on: February 16, 2019, 04:15:40 pm »
Hey, thank you for you help!

Append() only works for files of type Text (or it's synonym TextFile).
If the file already exists use Reset(), otherwise create it with Rewrite().
After Reset() uses seek() to go to the position in the file you want to be.

Bart

So how do I set the position to the end of the file then? I want to add new data to the existing data.

Append() only works for files of type Text (or it's synonym TextFile).
@Bart
That's not true Bart. It works for any typed file. Always has. Note that e.g. a file of a record type needs packed records. That is the only limitation.

I just searched google and tried to change my record into a packed record but it still didn't work. But I don't really know what I was doing, tbh  ::)

Thaddy

  • Hero Member
  • *****
  • Posts: 14165
  • Probably until I exterminate Putin.
Re: Usage of append
« Reply #4 on: February 16, 2019, 04:48:42 pm »
Bart was right. Append seems to only work for text files.  (AFAIK in ISO mode that is wrong)
That does not mean it is really an issue.

Example:
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyrecord = packed record
  3.     a:byte;
  4.     b:longint;
  5.   end;
  6.  
  7.   TMyFile = file of TMyrecord;
  8.  
  9. var
  10.   F:TMyFile;
  11.   a:TMyRecord;
  12. begin
  13. { write part }
  14.   Assign (f,'test.txt');
  15.   Rewrite (f);            
  16.   a.a := 1;
  17.   a.b :=1000;
  18.   write(f,a);
  19.   inc(a.a); { modify the record }
  20.   write(f,a); { does append }
  21.   Close(f);
  22.   a:= default(TMyrecord); { clear a }
  23. { read part }
  24.   Assign(f,'test.txt');
  25.   reset(f);
  26.   while not eof(f) do
  27.   begin
  28.     Read(f,a);
  29.     writeln(a.a);
  30.     writeln(a.b);
  31.  end;  
  32. end.
« Last Edit: February 16, 2019, 05:26:42 pm by Thaddy »
Specialize a type, not a var.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Usage of append
« Reply #5 on: February 16, 2019, 05:29:07 pm »
Something like Append() for non-text files may be like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyrecord = packed record
  3.     a:byte;
  4.     b:longint;
  5.   end;
  6.   TMyFile = file of TMyrecord;
  7.  
  8. var
  9.   F:TMyFile;
  10.  
  11. procedure OpenToAppend(var AFile: TMyFile; Filename: String);
  12. begin
  13.   Assign(AFile, Filename);
  14.   Reset(AFile);
  15.   Seek(AFile, FileSize(AFile));
  16. end;

Error-checking is left as an execise for the reader :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Thaddy

  • Hero Member
  • *****
  • Posts: 14165
  • Probably until I exterminate Putin.
Re: Usage of append
« Reply #6 on: February 16, 2019, 08:41:10 pm »
I leave it up to you to investigate why your answer is wrong: File of type is indexed by type....
Specialize a type, not a var.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Usage of append
« Reply #7 on: February 17, 2019, 12:55:16 am »
I leave it up to you to investigate why your answer is wrong: File of type is indexed by type....

Do you mean my answer? Let's see: Assign and Reset are normal; Seek() for typed files seeks to the given register and FileSize() gives the size in registers of the file, so:
Code: [Select]
Seek(AFile, FileSize(AFile));will let the file's position at the end of the file so the next write will append to the file. What's wrong with that?

In case you don't believe it, I've attached a test project.

ETA: In case any doubt arises, FileSize() is System.FileSize()
« Last Edit: February 17, 2019, 12:58:18 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

furious programming

  • Hero Member
  • *****
  • Posts: 836
Re: Usage of append
« Reply #8 on: February 17, 2019, 12:55:10 pm »
What's wrong with that?

Nothing. FileSize in this case returns the number of records in the file, not the size of the file in bytes. Seek in this case sets the cursor in the file also based on the size of the record.

Just see the implementation to make sure:

Code: Pascal  [Select][+][-]
  1. Function FileSize(var f:File):Int64;[IOCheck];
  2. {
  3.   Return the size of file f in records
  4. }
  5. Begin
  6.   FileSize:=0;
  7.   If InOutRes <> 0 then
  8.    exit;
  9.   case FileRec(f).Mode of
  10.     fmInOut,fmInput,fmOutput :
  11.       begin
  12.         if (FileRec(f).RecSize>0) then
  13.           FileSize:=Do_FileSize(FileRec(f).Handle) div FileRec(f).RecSize;
  14.       end;
  15.     else InOutRes:=103;
  16.   end;
  17. End;
  18.  
  19. Procedure Seek(var f:File;Pos:Int64);[IOCheck];
  20. {
  21.   Goto record Pos in file f
  22. }
  23. Begin
  24.   If InOutRes <> 0 then
  25.    exit;
  26.   case FileRec(f).Mode of
  27.     fmInOut,fmInput,fmOutput :
  28.       Do_Seek(FileRec(f).Handle,Pos*FileRec(f).RecSize);
  29.     else InOutRes:=103;
  30.   end;
  31. End;

The comments under the headlines clearly tell you what these routines are doing.
« Last Edit: February 17, 2019, 12:57:41 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

 

TinyPortal © 2005-2018