binaryfilesfreepascalrecordsuntyped-variables

Read / write different Records data from / to Untyped files in Pascal?


I've a programming project in my college.

Using a File type for storing data is allowed, and I did exactly like this one: pascal-programming

And, here's what I achieved so far:

  1. I tried to write the Records data into Untyped files instead and it worked

  2. I want to override a function with dynamic parameter (e.g: I can switch which Record I want to process, in this case there's 2 different "Records").

Open(var f: File; var data)

data = represent can receive "anything". cmiiw

  1. The reason why I did this, I don't think it's a good idea to recreate the same function over and over, e.g: when using 3 or more different "Records"

  2. I also encountered a problem that the files can't store or backup the actual binary files to the temporary "Records" variable, it always give the 0 values.

go to my github source code

my solution here doesn't provide any generic related procedures (check the last sentences):

program test_untyped;
{ A crude database recording }
uses crt;
type
   Temployee = record
                  name    : string[20];
                  address : string[40];
                  phone   : string[15];
                  age     : byte;
                  salary  : longint;
               end;
    arr_employee = array[1..100] of Temployee;

var
   F : File;
   c : char;
  //  r : Temployee;
   r, realR : arr_employee;
   s : string;
   i, j, n : integer;

procedure fRead;
begin
  seek(F, 0);
  i := 0;
  repeat
    clrscr;
    inc(i);
    writeln('increment: ', i); readln;
    writeln('File position : ',filepos(F));
    blockRead(F, r[i], sizeOf(Temployee));
    writeln('Name    = ', r[i].name);     { Input data }
    writeln('Address = ', r[i].address);
    writeln('Phone   = ', r[i].phone);
    writeln('Age     = ', r[i].age);
    writeln('Salary  = ', r[i].salary);
    write('Show data again (Y/N) ?');
    repeat
        c:=upcase(readkey);      { Ask user : Input again or not }
    until c in ['Y','N'];
    writeln(c);
    // realR[i] := r[i]; // backup, to show later
  until c='N';
end; // end fRead

procedure fWrite;
begin
  seek(F, filesize(F));
  repeat
    clrscr;
    inc(i);
    writeln('berapa nilai i: ', i);
    writeln('File position : ',filepos(F));
    write('Name    = '); readln(r[i].name);     { Input data }
    write('Address = '); readln(r[i].address);
    write('Phone   = '); readln(r[i].phone);
    write('Age     = '); readln(r[i].age);
    write('Salary  = '); readln(r[i].salary);
    blockWrite(F, r[i], sizeOf(Temployee)); { Write data to file }
    write('Input data again (Y/N) ?');
    repeat
        c:=upcase(readkey);      { Ask user : Input again or not }
    until c in ['Y','N'];
    writeln(c);
  until c='N';
end;

// procedure fDelete;
// var
//   nama: string;
//   delElement: integer;
//   tempR: Temployee;
// begin
//   seek(F, 0);
//   write('search your data by name: '); readln(nama);
//   while not eof(F) do
//   begin
//     writeln('file position: ', filePos(F));
//     blockRead(F, tempR, sizeOf(Temployee));
//     if (nama = tempR.name) then
//     begin
//       delElement := filePos(F);
//     end else
//     begin
//       // seek(F, )
//       blockWrite(F, tempR, sizeOf(Temployee));
//     end;
//   end;
// end; // end fDelete

procedure fDisplay;
begin
  writeln('nilai i saat ini: ', i); readln;
  for j := 1 to i do
  begin
    clrscr;
    writeln('Name    = ', r[j].name);     { Input data }
    writeln('Address = ', r[j].address);
    writeln('Phone   = ', r[j].phone);
    writeln('Age     = ', r[j].age);
    writeln('Salary  = ', r[j].salary);
    readln;
  end;
end;

begin
   clrscr;
  //  write('Input file name to record databases : '); readln(s);
   s := 'coba1.dat';

   assign(F,s);           { Associate it }
   {$I-}
   reset(F, sizeOf(Temployee));           { First, open it }
   {$I+}

   n:=IOResult;
   if n<>0 then           { If it's doesn't exist then }
   begin
      {$I-}
      rewrite(F, sizeOf(Temployee));      { Create it    }
      {$I+}
      n:=IOResult;
      if n<>0 then
      begin
         writeln('Error creating file !'); halt;
      end;
   end
   else
   begin                  { If it exists then }
      n:=filesize(F);     { Calculate total record }
      // seek(F,n);          { Move file pointer PAST the last record }
   end;

   fileMode := 2;
   reset(F, sizeOf(Temployee));
   fRead;
   fWrite;
   // fDelete;
   fDisplay;
  close(F);
end.

I'm wondering is the Pascal can be any good to use a generic programming? at least for this semester using Pascal in my college XD

Thank you and Best Regards,

EDIT: Pascal still doesn't support Generic Programming 'till the day I posted this question. So sad, really. You might wanna consider read this references instead.


Solution

  • I don't understand the main issue here, but would suggest using a typed file instead of an untyped one. An untyped file is much harder to maintain, and provides (in my eyes) no benefits.

    Consider the code:

    type
       Temployee = record
                      name    : string[20];
                      address : string[40];
                      phone   : string[15];
                      age     : byte;
                      salary  : longint;
                   end;
    VAR
      fEmployee : File Of Temployee;
      Employees : ARRAY[0..100] Of Temployee;
      Employee  : Temployee;
    
    PROCEDURE OpenEmployeeFile(CONST TheFileName:AnsiString);
      BEGIN
        AssignFile(fEmployee,TheFileName);
        IF FileExistsUTF8(TheFileName) { *Converted from FileExists* }
        THEN Reset(fEmployee)
        ELSE Rewrite(fEmployee);
      END;
    
    PROCEDURE CloseEmployeeFile;
      BEGIN
        Close(fEmployee);
      END;
    
    FUNCTION ReadEmployee(Position:WORD): Temployee;
      BEGIN
        Seek(fEmployee,Position);
        Read(fEmployee,Result);
      END;
    
    PROCEDURE WriteEmployee(CONST Employee:Temployee; Position:WORD);
      BEGIN
        Seek(fEmployee,Position);
        Write(fEmployee,Employee);
      END;
    

    Error handling not implemented. Code samples as a guideline, not complete. It provides a basic skeleton for opening and closing the employee-file, as well as reading and writing at specific positions (specific records) in the file.

    1. Open file.
    2. Write all the records you want.
    3. Close file.

    Or.

    1. Open file.
    2. Read all the records you want.
    3. Close file.