Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

matandked

• New Member
• Posts: 14
Save and write whole arrays of numbers to the text files
« on: February 03, 2017, 06:04:49 pm »

It seems that saving arrays to a binary files is quite easy (http://wiki.freepascal.org/File_Handling_In_Pascal#Binary_files)
However, I would like to read/write whole arrays from/to text/CSV files.

I can do this with for-loop statements (as I do in my code below which saves array to file), but I wonder if there's any better/simpler way of doing this in Free Pascal/Lazarus?
Maybe there's a counterpart of write.csv R! function (http://rprogramming.net/write-csv-in-r/)?

Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$mode objfpc}{\$H+}
4.
5. uses
8.   {\$ENDIF}{\$ENDIF}
9.   Classes, Sysutils;
10.
11. const
12.   C_FNAME = 'Array_Saved_to_TextFile.txt';
13.   // separate by tab:
14.   separator = Char(9);
15. var
16.   // I would like to save this array to text file
17.   // separated by tabs or any other character
18.   myArray: array [1..2,1..3] of Real =
19.     ((0.5, 2.4, 1.2), (3.4, 5.3, 6.5));
20.   slInfo: TStringList;
21.   row, column: Integer;
22.   line : String;
23.
24. begin
25.   If not FileExists(C_FNAME) Then
26.     begin
27.
28.       // I wonder if there's any simpler/better solution
29.       // For example if in Free Pascal there's counterpart of
30.       // R! write.table function
31.       /////////////////////////////////////////////////////////
32.       slInfo := TStringList.Create;
33.       For row:=1 to 2 do
34.           begin
35.             line := '';
36.             For column:=1 to 3 do
37.                 line := line + FloatToStr(myArray[row, column]) + separator;
38.           Delete (line,Length(Line),1);
40.           end;
41.
42.       slInfo.SaveToFile(C_FNAME);
43.       slInfo.Free;
44.       /////////////////////////////////////////////////////////
45.
46.
47.       WriteLn('Array has been saved in file: ' + Char(39) + C_FNAME + char(39));
48.     end
49.   else
50.       begin
51.         WriteLn('Following file already exists: ' + Char(39) + C_FNAME + Char(39));
52.       end;
54. end.
55.

• Hero Member
• Posts: 10993
Re: Save and write whole arrays of numbers to the text files
« Reply #1 on: February 03, 2017, 06:11:11 pm »
If you insist on storing the values in a human readable format, I am afraid, that your current effort comes close to a good solution. Thumbs up!
If that is not necessary, there are several options to speed things up, big time.

Can you explain - in a better way - why you need the human readable format?
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

lainz

• Hero Member
• Posts: 3874
Re: Save and write whole arrays of numbers to the text files
« Reply #2 on: February 03, 2017, 06:21:30 pm »
Maybe to be edited in a third party software, Excel or LibreOffice Calc

What I learned in university about CSV is that you need to specify (not necessary at all but useful) the width and height of the array, so you can call SetLength at the beginning, then load it line by line, instead of loading the entire text file in memory. If the file is not big you can use TStringList and for each N line do a new temporary TStringList and add the N line as delimitedtext or commatext, I don't remember wich one. Then you can access the horizontal data with an index of the temporary TStringList.

To save you already have a code, is the most simple part, you can specify here the width and height of the array (not needed if you use a TStringList, since it split the data with commatext or delimitedtext at loading time).

Another thing I've learned is that is a wrong code:

Code: Pascal  [Select][+][-]
1. For row:=1 to 2 do
2.
3. ...
4.
5. For column:=1 to 3 do
6.
Always refer to the array length, don't use any numeric constants 'magic numbers'. If you change the data length you will not need to change these numbers later.
« Last Edit: February 03, 2017, 06:23:46 pm by lainz »

Handoko

• Hero Member
• Posts: 4392
• My goal: build my own game engine using Lazarus
Re: Save and write whole arrays of numbers to the text files
« Reply #3 on: February 03, 2017, 06:30:09 pm »
Yes, 'magic numbers' should be avoid unless you are sure it won't change. So the better code is:

Code: Pascal  [Select][+][-]
1. const
2.   RowCount = 2;
3.   ColumnCount = 3;
4.
5. var
6.   myArray: array [1..RowCount, 1..ColumnCount] of Real = ...
7.
8. ...
9. for Row := 1 to RowCount do
10. ...
11.   for Column := 1 to ColumnCount do
12. ...
...
« Last Edit: February 03, 2017, 06:33:08 pm by Handoko »

matandked

• New Member
• Posts: 14
Re: Save and write whole arrays of numbers to the text files
« Reply #4 on: February 03, 2017, 06:44:15 pm »
Yes, 'magic numbers' should be avoid unless you are sure it won't change. So the better code is:

Code: Pascal  [Select][+][-]
1. const
2.   RowCount = 2;
3.   ColumnCount = 3;
4.
5. var
6.   myArray: array [1..RowCount, 1..ColumnCount] of Real = ...
7.
8. ...
9. for Row := 1 to RowCount do
10. ...
11.   for Column := 1 to ColumnCount do
12. ...
...

I wasn't aware that it is possible to do that in FreePascal - I expected that I will be able to get them in different way for example: myArray.GetNumberOfRows
Thank you!!!

If you insist on storing the values in a human readable format, I am afraid, that your current effort comes close to a good solution. Thumbs up!
If that is not necessary, there are several options to speed things up, big time.

Can you explain - in a better way - why you need the human readable format?

Thank you for a quick response.

The only reason is that end users requested to have output in Excel and text file/human readable formats, because they're familiar with them.

Generally speaking I was asked to write a program that:
• will read data from a set of Excel workbooks or text files
• perform calculations (currently I have no details, but there will be some simple arithmetic operations as well as linear programming tasks) on just read arrays of numbers
• save output to Excel spreadsheet and text file

Off topic
I'm not sure if there's any ready-to-use function to read Excel range of cells as Free Pascal array (in such case I will need to write another loop again to iterate over cells in range  ).
Anyway, I think that it will be better way to firstly read all numbers as arrays and then performing operations on them (am I correct or should I change all my assumptions from the beginning
Besides I haven't checked yet if Free Pascal has any library for table/matrix operations (so that I will be able to write shorter code such as in Octave/Matlab), but I assume that yes - it seems to be a cool language from the new user perspective

User137

• Hero Member
• Posts: 1791
Re: Save and write whole arrays of numbers to the text files
« Reply #5 on: February 04, 2017, 11:24:08 am »
You don't have to use consts if you don't want to. High() and Low() returns the array range. These 2 ways do the same
Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. var row, column: integer;
3. begin
4.   //for Row := 1 to RowCount do
5.     //for Column := 1 to ColumnCount do begin
6.   for Row := 1 to high(myArray) do
7.     for Column := 1 to high(myArray[1]) do begin
9.     end;
10. end;
I didn't use low() because i assumed it starts from 1. In most cases i prefer starting all arrays from 0 though, because that's what machines tend to like most.

maurobio

• Sr. Member
• Posts: 304
• Ecology is everything.
Re: Save and write whole arrays of numbers to the text files
« Reply #6 on: September 25, 2021, 11:43:46 pm »
Dear ALL,

Here is my humble contribution to the question presented by @matendked:

Code: Pascal  [Select][+][-]
1. program test;
2.
3. {\$APPTYPE CONSOLE}
4.
5. uses Classes, SysUtils, StrUtils;
6.
7. type
8.         TMatrix = array of array of double;
9.
10. var
11.         n, m, i, j: integer;
12.         arr: TMatrix;
13.
14. procedure SaveArray(filename: string; n, m: integer; arr: TMatrix; separator: char; format: char);
15. var
16.   slInfo: TStringList;
17.   row, col: integer;
18.   line: string;
19. begin
20.   slInfo := TStringList.Create;
21.   for row := 0 to n - 1 do
22.   begin
23.     line := '';
24.     for col := 0 to m - 1 do
25.         begin
26.       if format = 'i' then
27.                 line := line + FloatToStrF(arr[row, col], ffFixed, 5, 0) + separator
28.           else if format = 'f' then
29.                 line := line + FloatToStrF(arr[row, col], ffFixed, 7, 2) + separator;
30.         end;
31.     Delete(line, Length(line), 1);
33.   end;
34.   slInfo.SaveToFile(filename);
35.   slInfo.Free;
36. end;
37.
38. procedure ReadArray(filename: string; separator: char; var a: TMatrix; var n, m: integer);
39. var
40.         SL, TL: TStringList;
41.         I, J: integer;
42. begin
43.   SL := TStringList.Create;
45.   n := SL.Count;
46.   m := SL[0].CountChar(separator) + 1;
47.   SetLength(a, n, m);
48.   for I := 0 to n - 1 do
49.   begin
50.         TL := TStringList.Create;
51.         TL.Delimiter := separator;
52.     TL.DelimitedText := SL[I];
53.         for J := 0 to m - 1 do
54.                 a[I, J] := StrToInt(TL[J]);
55.     TL.Free;
56.   end;
57.   SL.Free;
58. end;
59.
60. begin
61.         ReadArray('test.csv', ',', arr, n, m);
62.         WriteLn(n, ' rows, ', m, ' cols');
63.         for i := 0 to n - 1 do
64.         begin
65.                 for j := 0 to m - 1 do
66.                         Write(arr[i, j]:5:0);
67.                 WriteLn;
68.         end;
69.         SaveArray('test2.csv', n, m, arr, ';', 'i');
70. end.
71.
Procedures ReadArray and SaveArray are inspired by the savetxt and loadtxt functions from Python Numpy library.

Hope it helps.

With best wishes,
UCSD Pascal / Burroughs 6700 / Master Control Program
Lazarus 2.0.12 - FPC 3.2.0 on GNU/Linux Mint 19, GNU/Linux Lubuntu 18.04, Windows XP SP3, Windows 7 Professional, Windows 10 Home

Bart

• Hero Member
• Posts: 4516
Re: Save and write whole arrays of numbers to the text files
« Reply #7 on: September 26, 2021, 11:21:03 am »
In LazuTils there is a unit called lcsvutils that proviedes methods for reading and writing CSV documents.

Also fpc should have CsvDocument since version 3.0 (according to this wikipage).

FpSpreadSheet is your best bet at writing excel files, you don't need a working Excel on the system to create or read the files (no COM).

I have a small subset of write functions to Excel version 2.0 (text fields only), which might suffice.

Bart

• Hero Member
• Posts: 10993
Re: Save and write whole arrays of numbers to the text files
« Reply #8 on: September 26, 2021, 12:51:30 pm »
I didn't use low() because i assumed it starts from 1.
That is a wrong assumption. Dynamic arrays always start at zero.

Aside: you can actually flatten the array loops into a single one by multiplication of n and m.
That should be a little faster.
« Last Edit: September 26, 2021, 12:53:13 pm 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.

BobDog

• Full Member
• Posts: 170
Re: Save and write whole arrays of numbers to the text files
« Reply #9 on: September 26, 2021, 04:26:48 pm »

With 'msvcrt.dll' (I think just 'c' in linux), you can block load and save
Code: Pascal  [Select][+][-]
1. program matrixtofile;
2.
3.     function fopen (p1:pchar; p2:pchar):pointer ; cdecl external 'msvcrt.dll' name 'fopen';
5.     function fwrite (p1:pointer;i1:integer;i2:integer;_FILE: pointer):integer ; cdecl external 'msvcrt.dll' name 'fwrite';
6.     function fclose (_FILE:pointer):integer   cdecl external 'msvcrt.dll' name 'fclose';
7.
8.
9.   type matrix=array of array of real;
10.
11.
12.        function DeleteFile(filename: string): Boolean;
13.          var
14.          F: file;
15.          begin
16.          Assign(F, filename);
17.         {\$I-}
18.         Erase(F);
19.        {\$I+}
20.        DeleteFile:=IOResult=0;
21.        end;
22.
23.         procedure savefile(content:matrix;filename:pchar);
24.        var
25.        w:pchar='wb';
26.        fp:pointer;
27.        begin
28.        fp:=fopen(filename,w);
29.        if fp = nil then
30.        begin
31.        writeln( 'Unable to save  ',filename);
32.        exit
33.        end;
34.        fwrite(pointer(content), 1, sizeof(content)*length(content), fp);
35.         fclose(fp);
36.        end;
37.
38.
40.        var
41.        w:pchar='rb';
42.        fp:pointer;
43.        begin
44.        fp:=fopen(filename,w);
45.        if fp = nil then
46.        begin
47.        writeln( 'Unable to open  ',filename);
48.        exit
49.        end;
51.         fclose(fp);
52.        end;
53.
54.
55.    var
56.    i,j:int32;
57.    filename:pchar='array.dat';
58.     m: matrix;
59.     ret:matrix;
60.
61.
62.    begin
63.     SetLength(m,3,4);
64.
65.      m[1,1]:=0.5;
66.      m[1,2]:=2.4 ;
67.      m[1,3]:=1.2;
68.
69.      m[2,1]:=3.4;
70.      m[2,2]:=5.3 ;
71.      m[2,3]:=6.5;
72.
73.     writeln('To file');
74.     for i:=1 to 2 do
75.       for j:=1 to 3 do
76.       begin
77.       write(m[i,j],',');
78.       if (j=3) then writeln;
79.       end;
80.
81.     savefile(m,filename);
82.
83.
84.      SetLength(ret,3,4);
85.
87.
88.         writeln;
89.        writeln('from file');
90.       for i:=1 to 2 do
91.       for j:=1 to 3 do
92.       begin
93.       write(ret[i,j],',');
94.       if (j=3) then writeln;
95.       end;
96.       writeln;
97.       writeln(deletefile(filename));
99.
100.    end.
101.

Bart

• Hero Member
• Posts: 4516
Re: Save and write whole arrays of numbers to the text files
« Reply #10 on: September 26, 2021, 09:19:56 pm »
With 'msvcrt.dll' (I think just 'c' in linux), you can block load and save

No need for all that, there is old fashioned BlockRead and BlockWrite.
Or use a TFileStream.

Bart

BobDog

• Full Member
• Posts: 170
Re: Save and write whole arrays of numbers to the text files
« Reply #11 on: September 26, 2021, 09:46:03 pm »

Hello Bart
I don't see any block read/write or Tfilestream examples here, they all loop through a matrix.
Yes, my contribution is a bit out of the pascal box, but it is an answer, of sorts, to matendked's first post - (I would like to read/write whole arrays from/to text/CSV files).

wp

• Hero Member
• Posts: 9051
Re: Save and write whole arrays of numbers to the text files
« Reply #12 on: September 26, 2021, 11:13:18 pm »
Here is a tested example for writing/reading a matrix by means of BlockWrite/BlockRead.

I think it is very important to understand that there is a big difference between static and dynamic matrices. In a static matrix, the dimension is given by the type at compile time (array[0..1, 0..2] of Double for a 2x3 matrix), and in this case the matrix simply can be written by calling BlockWrite(F, M, SizeOf(M)). This works because this kind of matrix is a contiguous array of double values

A dynamic matrix which is dimensioned at run time, e.g. by calling SetLength(M, 2, 3). Essentially M is pointer. It points to another array of pointers which in turn point to an array of values in each row. The row values do occupy contiguous memory blocks, but a row is not immediately adjacent to the previous row! Therefore writing (and reading) is more complicated - this cannot be avoided:
- First: Write the number of rows and columns
- Second: Iterate through the rows. The first value in each row is M[row, 0]. Use this as argument in the BlockWrite command. And the number of bytes to be written is the number of columns times the size of a double.

Ah, and of course, I must mention that this memory map is valid only when the first index of the matrix is the row index, and the second index is the column index  - just like in mathematics.

And finally it must be mentioned that dynamic array ALWAYS begin at index 0.  This is against math convention which begins at 1. For sake of your mental sanity, never attempt to allocate one excess matrix element per row and per column because you want to begin your matrix with index 1. Pretty soon your head will be spinning because you never know whether your matrices are correctly allocated. And Lazarus is not forgiving any mistake here.

Code: Pascal  [Select][+][-]
1. program matrixtofile;
2.
3. uses
4.   SysUtils;
5.
6. type
7.   { It is assumed that the first index is the row index, the second index is the
8.     column index
9.
10.       ( m00 m01 m02 m03 m04 ... )
11.       ( m10 m11 m12 m13 m14 ... )
12.       ( ...                     )      }
13.   TMatrix = array of array of Double;
14.   TMatrix_2x3 = packed array[0..1, 0..2] of Double;
15.
16. procedure SaveMatrixToFile(const M: TMatrix; AFileName: String);
17. var
18.   F: File;
19.   nr, nc, r: Integer;
20. begin
21.   if FileExists(AFileName) then
22.     DeleteFile(AFileName);
23.
24.   AssignFile(F, AFileName);
25.   Rewrite(F);
26.   // Write the number of rows first
27.   nr := Length(M);
28.   BlockWrite(F, nr, SizeOf(nr));
29.   // Write the number of columns
30.   nc := Length(M[0]);
31.   BlockWrite(F, nc, SizeOf(nc));
32.   // Write rows - there's number after number in the rows (but not row by row!)
33.   for r := 0 to nr-1 do
34.     // Per row, there are nc columns, each one has the size of a Double
35.     BlockWrite(F, M[r, 0], nc*SizeOf(Double));
36.   CloseFile(F);
37. end;
38.
39. procedure SaveMatrix2x3ToFile(const M: TMatrix_2x3; AFileName: String);
40. var
41.   F: File;
42. begin
43.   if FileExists(AFileName) then
44.     DeleteFile(AFileName);
45.
46.   AssignFile(F, AFileName);
47.   Rewrite(F);
48.   // Write the matrix in one single call. This is possible because the numbers
49.   // follow one each other. The first number is M[0,0].
50.   BlockWrite(F, M, SizeOf(TMatrix_2x3));
51.   CloseFile(F);
52. end;
53.
54. procedure LoadMatrixFromFile(var M: TMatrix; AFileName: String);
55. var
56.   F: File;
57.   nr: Integer = 0;
58.   nc: Integer = 0;
59.   r: Integer;
60.   n: Integer;
61. begin
62.   AssignFile(F, AFileName);
63.   Reset(F);
64.   // Read number of rows
66.   // Read number of cols
68.   // Allocate memory for matrix data
69.   SetLength(M, nr, nc);
70.   // Read row by row
71.   for r := 0 to nr-1 do
72.   begin
73.     BlockRead(F, M[r, 0], nc*SizeOf(Double), n);
74.     if n <> nc*SizeOf(Double) then
76.   end;
77.   CloseFile(F);
78. end;
79.
80. procedure LoadMatrix2x3FromFile(var M: TMatrix_2x3; AFileName: String);
81. var
82.   F: File;
83. begin
84.   AssignFile(F, AFileName);
85.   Reset(F);
87.   CloseFile(F);
88. end;
89.
90. var
91.   M: TMatrix;
92.   M23: TMatrix_2x3;
93.   i, j: Integer;
94. begin
95.   // Begin with static array
96.   WriteLn('*** STATIC ARRAY ***');
97.   M23[0, 0] := 0.5;
98.   M23[0, 1] := 2.4;
99.   M23[0, 2] := 1.2;
100.
101.   M23[1, 0] := 3.4;
102.   M23[1, 1] := 5.3;
103.   M23[1, 2] := 6.5;
104.
105.   for i := 0 to 1 do
106.   begin
107.     for j := 0 to 2 do
108.       Write(M23[i, j]:5:1);
109.     WriteLn;
110.   end;
111.   WriteLn;
112.
113.   SaveMatrix2x3ToFile(M23, 'test23.mat');
114.   FillChar(M23, Sizeof(M23), 0);
116.
117.   for i := 0 to 1 do
118.   begin
119.     for j := 0 to 2 do
120.       Write(M23[i, j]:5:1);
121.     WriteLn;
122.   end;
123.   WriteLn;
124.
125.   // Now repeat with dynamic array
126.   WriteLn('*** DYNAMIC ARRAY ***');
127.   SetLength(M, 2, 3);
128.
129.   M[0, 0] := 0.5;
130.   M[0, 1] := 2.4;
131.   M[0, 2] := 1.2;
132.
133.   M[1, 0] := 3.4;
134.   M[1, 1] := 5.3;
135.   M[1, 2] := 6.5;
136.
137.   for i := 0 to 1 do
138.   begin
139.     for j := 0 to 2 do
140.       Write(M[i, j]:5:1);
141.     WriteLn;
142.   end;
143.   WriteLn;
144.
145.   SaveMatrixToFile(M, 'test.mat');
146.   for i := 0 to 1 do
147.     for j := 0 to 2 do
148.       M[i, j] := 0;
150.
151.   for i := 0 to 1 do
152.   begin
153.     for j := 0 to 2 do
154.       Write(M[i, j]:5:1);
155.     WriteLn;
156.   end;
157.   WriteLn;
158.
159.   WriteLn('Press ENTER to quit...');
161. end.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

BobDog

• Full Member
• Posts: 170
Re: Save and write whole arrays of numbers to the text files
« Reply #13 on: September 27, 2021, 12:30:07 am »

Thank you for your excellent treatise wp.
Of course a matrix is always 1,1 based, to use 0,0 base in a dynamic array here would confuse me, so the 0 element is not used, saved and loaded from file yes, but ignored-AND REMEMBERED.
I have set a static matrix 1,1 based, I have also overloaded all these C procedures for dynamic and static matrices.
Code: Pascal  [Select][+][-]
1. program matrixtofile;
2.
3.     function fopen (p1:pchar; p2:pchar):pointer ; cdecl external 'msvcrt.dll' name 'fopen';
5.     function fwrite (p1:pointer;i1:integer;i2:integer;_FILE: pointer):integer ; cdecl external 'msvcrt.dll' name 'fwrite';
6.     function fclose (_FILE:pointer):integer   cdecl external 'msvcrt.dll' name 'fclose';
7.
8.
9.   type matrixd=array of array of real;
10.   type matrix= packed array[1..2, 1..3] of real;
11.
12.
13.        function DeleteFile(filename: string): Boolean;
14.          var
15.          F: file;
16.          begin
17.          Assign(F, filename);
18.         {\$I-}
19.         Erase(F);
20.        {\$I+}
21.        DeleteFile:=IOResult=0;
22.        end;
23.
24.         procedure savefile(content:matrix;filename:pchar);
25.        var
26.        w:pchar='wb';
27.        fp:pointer;
28.        begin
29.        fp:=fopen(filename,w);
30.        if fp = nil then
31.        begin
32.        writeln( 'Unable to save  ',filename);
33.        exit
34.        end;
35.         fwrite((@content[1,1]), 1, sizeof(content), fp);
36.         fclose(fp);
37.        end;
38.
39.         procedure savefile(content:matrixD;filename:pchar);
40.        var
41.        w:pchar='wb';
42.        fp:pointer;
43.        begin
44.        fp:=fopen(filename,w);
45.        if fp = nil then
46.        begin
47.        writeln( 'Unable to save  ',filename);
48.        exit
49.        end;
50.        fwrite(pointer(content), 1, sizeof(content)*length(content), fp);
51.         fclose(fp);
52.        end;
53.
55.        var
56.        w:pchar='rb';
57.        fp:pointer;
58.        begin
59.        fp:=fopen(filename,w);
60.        if fp = nil then
61.        begin
62.        writeln( 'Unable to open  ',filename);
63.        exit
64.        end;
66.         fclose(fp);
67.        end;
68.
70.        var
71.        w:pchar='rb';
72.        fp:pointer;
73.        begin
74.        fp:=fopen(filename,w);
75.        if fp = nil then
76.        begin
77.        writeln( 'Unable to open  ',filename);
78.        exit
79.        end;
81.         fclose(fp);
82.        end;
83.
84.
85.    var
86.    i,j:int32;
87.    filename:pchar='array.dat';
88.     m: matrix;
89.     ret:matrix;
90.     m2:matrixD;
91.     ret2:matrixD;
92.
93.
94.    begin
95.       //================ static ======================
96.      m[1,1]:=0.5;
97.      m[1,2]:=2.4 ;
98.      m[1,3]:=1.2;
99.
100.      m[2,1]:=3.4;
101.      m[2,2]:=5.3 ;
102.      m[2,3]:=6.5;
103.
104.     writeln('To file - staic');
105.     for i:=1 to 2 do
106.       for j:=1 to 3 do
107.       begin
108.       write(m[i,j],',');
109.       if (j=3) then writeln;
110.       end;
111.
112.     savefile(m,filename);
113.
114.       FillChar(ret, Sizeof(ret), 0);
116.         writeln;
117.        writeln('from file - static');
118.       for i:=1 to 2 do
119.       for j:=1 to 3 do
120.       begin
121.       write(ret[i,j],',');
122.       if (j=3) then writeln;
123.       end;
124.       writeln;
125.
126.       //================ dynamic ======================
127.        SetLength(m2,3,4);
128.      m2[1,1]:=-0.5;
129.      m2[1,2]:=-2.4 ;
130.      m2[1,3]:=-1.2;
131.
132.      m2[2,1]:=-3.4;
133.      m2[2,2]:=-5.3 ;
134.      m2[2,3]:=-6.5;
135.
136.      writeln('To file - dynamic');
137.     for i:=1 to 2 do
138.       for j:=1 to 3 do
139.       begin
140.       write(m2[i,j],',');
141.       if (j=3) then writeln;
142.       end;
143.       savefile(m2,filename);
144.
145.       setlength(ret2,3,4);
147.         writeln;
148.        writeln('from file - dynamic');
149.       for i:=1 to 2 do
150.       for j:=1 to 3 do
151.       begin
152.       write(ret2[i,j],',');
153.       if (j=3) then writeln;
154.       end;
155.       writeln;
156.       writeln(deletefile(filename));
158.
159.    end.
160.
It seems to work, but I note that some members dislike using 'msvcrt.dll', and I don't know if 'c' works in Linux.
By the way, you say that :
"And Lazarus is not forgiving any mistake here"
I haven't tested using the Lazarus ide, I use a simple ide for pascal.
fpc 3.2.2, 64 bits, win 10.
Thank you again.

jamie

• Hero Member
• Posts: 5052
Re: Save and write whole arrays of numbers to the text files
« Reply #14 on: September 27, 2021, 01:18:52 am »
In Pascal arrays can start at any value, not just 0 but that is only for the compiler, they all start at the same place.

so if you want to index via 1 instead of 0 for the start, then you specify that. the starting place for 1 is the same address as a starting place of 0.

when you save and load these arrays, they will be placed at the same position, the start, no matter the way they were originally saved.

Pascal allows you to specify an array to start at any value as a i said, that does mean they are actually starting up stream somewhere, they are not. Its for the compiler to know what it needs to offset the values for to obtain the 0 offset from values your code indexes the address with.

The only true wisdom is knowing you know nothing