Recent

Author Topic: Save and write whole arrays of numbers to the text files  (Read 8311 times)

wp

  • Hero Member
  • *****
  • Posts: 8881
Re: Save and write whole arrays of numbers to the text files
« Reply #15 on: September 27, 2021, 10:44:44 am »
jamie, no debate on static arrays, but dynamic array always start with index 0.

BogDob, of course you can try dynamic arrays with one extra element to begin with index 1 for your use. But I doubt that you (or worse, every other programmer seeing your code) will remember that always. Your code will be full of unlogical things like SetLength(matrix, n+1, m+1) where n und m are the matrix dimensions (1-based), or n := Length(matrix)-1, or first_row_index := Low(matrix)+1. All other dynamic arrays in your code, as well as list elements (TStringList, TList, ...) are 0-based and miss that additional 1. That's highly error-prone.

The only situation in which I myself would accept such an "extended" pseudo-1-based dynamic array is inside a class/object which hides all these internal details from the user, e.g:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. type
  4.   TMatrix = object
  5.   private
  6.     FElements: array of array of double;
  7.     function GetElement(i, j: Integer): Double;  // i/j 1-based
  8.     procedure GetSize(out n, m: Integer);
  9.     procedure SetElement(i, j: Integer; AValue: Double);
  10.   public
  11.     procedure Init(n, m: Integer);
  12.     // procedure Done;  // not needed because FElements is destroyed automatically.
  13.     property Elements[i, j: Integer]: Double read GetElement write SetElement; default;
  14.   end;
  15.  
  16.   procedure TMatrix.Init(n, m: Integer);
  17.   begin
  18.     SetLength(FElements, n+1, m+1);
  19.   end;
  20.  
  21.   function TMatrix.GetElement(i, j: Integer): Double;
  22.   begin
  23.     Result := FElements[i-1, j-1];
  24.   end;
  25.  
  26.   procedure TMatrix.GetSize(out n, m: Integer);
  27.   begin
  28.     n := Length(FElements)-1;
  29.     m := Length(FElements[0])-1;
  30.   end;
  31.  
  32.   procedure TMatrix.SetElement(i, j: Integer; AValue: Double);
  33.   begin
  34.     FElements[i-1, j-1] := AValue;
  35.   end;
  36.  
  37. var
  38.   Mat: TMatrix;
  39.   i, j: Integer;
  40.   n, m: Integer;
  41. begin
  42.   Mat.Init(2, 2);
  43.   Mat[1, 1] := 11;
  44.   Mat[1, 2] := 12;
  45.   Mat[2, 1] := 21;
  46.   Mat[2, 2] := 22;
  47.   Mat.GetSize(n, m);
  48.   for i := 1 to n do
  49.   begin
  50.     for j := 1 to m do
  51.       Write(Mat[i, j]:5:0);
  52.     WriteLn;
  53.   end;
  54.  
  55.   ReadLn;
  56. end.  /code]
  57.  
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

BobDog

  • Full Member
  • ***
  • Posts: 140
Re: Save and write whole arrays of numbers to the text files
« Reply #16 on: September 27, 2021, 11:32:49 am »

Hi wp
I think you just have to get into a matrix mode for the (type matrix) and throw extreme caution to the wind.
I have tried a matrix object in other languages, it is all very well, but I always have preferred straight arrays for matrix operations, they are faster and cleaner IMHO.
My previous matrix mode in this forum:
https://forum.lazarus.freepascal.org/index.php/topic,55254.msg410793.html#msg410793
And of course the dynamic array approach is better I think.
Just look upon the operation as using a subset of the pointer.
But then again nobody responded to my matrix in that post, so you might have the better idea after all.





Thaddy

  • Hero Member
  • *****
  • Posts: 10920
Re: Save and write whole arrays of numbers to the text files
« Reply #17 on: September 27, 2021, 11:40:35 am »
You really do not have to use msvcrt since Pascal has all the equivalents for the filehandling you do here.
See the examples in the manual.
Here is one of them:
Code: Pascal  [Select][+][-]
  1. Program Example6;
  2.  
  3. { Program to demonstrate the BlockRead and BlockWrite functions. }
  4.  
  5. Var Fin, fout : File;
  6.     NumRead,NumWritten : Word;
  7.     Buf : Array[1..2048] of byte;
  8.     Total : Longint;
  9.  
  10. begin
  11.   Assign (Fin, Paramstr(1));
  12.   Assign (Fout,Paramstr(2));
  13.   Reset (Fin,1);
  14.   Rewrite (Fout,1);
  15.   Total:=0;
  16.   Repeat
  17.     BlockRead (Fin,buf,Sizeof(buf),NumRead);
  18.     BlockWrite (Fout,Buf,NumRead,NumWritten);
  19.     inc(Total,NumWritten);
  20.   Until (NumRead=0) or (NumWritten<>NumRead);
  21.   Write ('Copied ',Total,' bytes from file ',paramstr(1));
  22.   Writeln (' to file ',paramstr(2));
  23.   close(fin);
  24.   close(fout);
  25. end.
The link is here and subsequent links can be found there too:
https://www.freepascal.org/docs-html/rtl/system/blockread.html
This is also fully cross-platform and only uses the system unit.

But as suggested,  TFilestream is a bit more convenient.
« Last Edit: September 27, 2021, 11:42:23 am by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

 

TinyPortal © 2005-2018