Lazarus

Programming => General => Topic started by: OC DelGuy on January 31, 2023, 03:19:34 am

Title: File not open??? Why?
Post by: OC DelGuy on January 31, 2023, 03:19:34 am
I just wrote this procedure  Why is the file "Not Open"?
Code: Pascal  [Select][+][-]
  1. Procedure WriteVillagedata;   // This will write the Data Structure to file.
  2.   Var
  3.     x, y : Integer;
  4.   Begin
  5.     Assignfile(FilenameOut, 'VillageData.txt');
  6.     Try
  7.       ReWrite(FilenameOut);
  8.       For x := 1 to recds do
  9.         Begin
  10.           WriteLn(FilenameOut, Villages[x].Name);            This is line 60 as referred to in the error message.
  11.           WriteLn(FilenameOut, Villages[x].Inn);
  12.           WriteLn(FilenameOut, Villages[x].Government);
  13.           WriteLn(FilenameOut, Villages[x].Population);
  14.           WriteLn(FilenameOut, Villages[x].Families);
  15.           WriteLn(FilenameOut, Villages[x].Farmers);
  16.           WriteLn(FilenameOut, Villages[x].Artisans);
  17.           WriteLn(FilenameOut, Villages[x].Laborers);
  18.           WriteLn(FilenameOut, Villages[x].Paupers);
  19.           For y := 1 to 3 do
  20.             Begin
  21.               WriteLn(FilenameOut, Villages[x].Gods[y]);
  22.               WriteLn(FilenameOut, Villages[x].Taverns[y]);
  23.               WriteLn(FilenameOut, Villages[x].Trade[y]);
  24.             end; {For y}
  25.           Close(FilenameOut);
  26.         End; {For x}
  27.     finally
  28.     end; {Try}
  29.   end; {Proc WriteVillagedata}
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 03:40:11 am
Try not to close the file in your loop, does it help?
Code: Pascal  [Select][+][-]
  1. Procedure WriteVillagedata;   // This will write the Data Structure to file.
  2.   Var
  3.     x, y : Integer;
  4.     FilenameOut: TextFile;
  5.   Begin
  6.     Assignfile(FilenameOut, 'VillageData.txt');
  7.     Try
  8.       ReWrite(FilenameOut);
  9.       For x := 1 to recds do
  10.         Begin
  11.           WriteLn(FilenameOut, Villages[x].Name);            This is line 60 as referred to in the error message.
  12.           WriteLn(FilenameOut, Villages[x].Inn);
  13.           WriteLn(FilenameOut, Villages[x].Government);
  14.           WriteLn(FilenameOut, Villages[x].Population);
  15.           WriteLn(FilenameOut, Villages[x].Families);
  16.           WriteLn(FilenameOut, Villages[x].Farmers);
  17.           WriteLn(FilenameOut, Villages[x].Artisans);
  18.           WriteLn(FilenameOut, Villages[x].Laborers);
  19.           WriteLn(FilenameOut, Villages[x].Paupers);
  20.           For y := 1 to 3 do
  21.             Begin
  22.               WriteLn(FilenameOut, Villages[x].Gods[y]);
  23.               WriteLn(FilenameOut, Villages[x].Taverns[y]);
  24.               WriteLn(FilenameOut, Villages[x].Trade[y]);
  25.             end; {For y}
  26.         End; {For x}
  27.     finally
  28.       Close(FilenameOut);
  29.     end; {Try}
  30.   end; {Proc WriteVillagedata}
Title: Re: File not open??? Why?
Post by: jamie on January 31, 2023, 03:41:26 am
Assign(...) instead of AssignFile?


Title: Re: File not open??? Why?
Post by: Bogen85 on January 31, 2023, 03:44:58 am
Assign(...) instead of AssignFile?

That is fine.

Code: Pascal  [Select][+][-]
  1. program wvd;
  2. {$mode objfpc}
  3.  
  4. Procedure WriteVillagedata;   // This will write the Data Structure to file.
  5.   Var
  6.     x, y : Integer;
  7.   FilenameOut: textfile;
  8.   Begin
  9.     Assignfile(FilenameOut, 'VillageData.txt');
  10.     Try
  11.       ReWrite(FilenameOut);
  12.       writeln(FilenameOut, 'text');
  13.     finally
  14.       close(FilenameOut);
  15.     end; {Try}
  16.   end; {Proc WriteVillagedata}
  17.  
  18. begin
  19.   WriteVillagedata;
  20. end.
  21.  

The above works, @KodeZwerg likely caught the problem, the close file being in the loop.
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 03:54:16 am
Maybe also his "FilenameOut" is wrong, since he not show, I added that on my own as local.
Title: Re: File not open??? Why?
Post by: Thaddy on January 31, 2023, 05:52:50 am
If it has to be old school, I would write it like so:
Code: Pascal  [Select][+][-]
  1. program wvd;
  2. Procedure WriteVillagedata;   // This will write the Data Structure to file.
  3.   Var
  4.     e:Integer;
  5.     FilenameOut: textfile;
  6.   Begin
  7.     Assign(FilenameOut, 'VillageData.txt');
  8.     {$push}{$I-  because we want to handle IOResult ourselves. This can be local}
  9.     ReWrite(FilenameOut);
  10.     e:= IOResult;// because IOResult gets cleared after access, store it!!
  11.     {$pop}
  12.     if e = 0 then Try
  13.       writeln(FilenameOut, 'text');
  14.     finally
  15.       flush(FilenameOut);
  16.       close(FilenameOut);
  17.     end else writeln ('error: ', e);
  18.   end;
  19. begin
  20.   WriteVillagedata;
  21. end.
I suspect that when examining IOResult the original code will show an error...
Also, just to be sure, call flush() before closing.
Anyway, if you pull in classes better to use a TFileStream and if you pull in sysutils, use exception objects.
Assign() - or the hidious AssignFile(), which is mode dependent - does not cause IOResult to be set, but rewrite() will... And now we handle 103 the proper way.
Errors are here: https://www.freepascal.org/docs-html/rtl/system/ioresult.html

Note, of course Bogen85's example code on which I based this, also works in most cases, I just added error handling the olden way.
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 06:18:07 am
If it has to be old school
I doubt that, so I show a more modern way:
Code: Pascal  [Select][+][-]
  1. procedure WriteVillagedata;   // This will write the Data Structure to file.
  2. var
  3.   x, y: Integer;
  4.   sl  : TStrings;
  5. begin
  6.   sl := TStringList.Create;
  7.   try
  8.     for x := 1 to recds do
  9.     begin
  10.       sl.Add(Villages[x].Name);
  11.       sl.Add(Villages[x].Inn);
  12.       sl.Add(Villages[x].Government);
  13.       sl.Add(Villages[x].Population);
  14.       sl.Add(Villages[x].Families);
  15.       sl.Add(Villages[x].Farmers);
  16.       sl.Add(Villages[x].Artisans);
  17.       sl.Add(Villages[x].Laborers);
  18.       sl.Add(Villages[x].Paupers);
  19.       for y := 1 to 3 do
  20.       begin
  21.         sl.Add(Villages[x].Gods[y]);
  22.         sl.Add(Villages[x].Taverns[y]);
  23.         sl.Add(Villages[x].Trade[y]);
  24.       end; {For y}
  25.     end; {For x}
  26.     sl.SaveToFile(ExtractFilePath(ParamStr(0)) + 'VillageData.txt'); // <<<--- I strongly suggest to add a path infront of filename
  27.   finally
  28.     sl.Free;
  29.   end;
  30. end;
Ofc the record stuff I can't check but at least you see some logic.
Title: Re: File not open??? Why?
Post by: Thaddy on January 31, 2023, 06:30:09 am
Yup, something like that (missing exception handling, though?)
Note I wrote "old school", but there is relevance on memory or hardware starved systems that do not use classes or sysutils, like many embedded systems. It is more lightweight and also a bit more portable.
I would also use packed records and write an entry in one go. And of course  ;D count from zero  :D
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 06:59:53 am
Yup, something like that (missing exception handling, though?)
Uhm... the only "error handling" that comes in my mind would be to test if file exists, try to delete, when that succeed write it.
Do you have something different in your mind that I am currently not aware of?
Or you meant a seperate "try/except" around the SaveToFile() ?
As longer I think about, as more strange stuff come in my head  %) (I usual just let the class do the job...)

And of course  ;D count from zero  :D
Absolute! Thats why I noted:
Ofc the record stuff I can't check but at least you see some logic.
( Where I actual meant an array  :-[  :-X  :P )
Title: Re: File not open??? Why?
Post by: egsuh on January 31, 2023, 07:55:08 am
I believe the first answer is correct. File is closed after first x loop in the original example.
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 08:07:49 am
And of course  ;D count from zero  :D
Code: Pascal  [Select][+][-]
  1.     for x := 1 to recds do
Me dummy, ofc it should be written like that:
Code: Pascal  [Select][+][-]
  1.     for x := Low(Villages) to High(Villages) do
And he does not need to think about, or what does "recds" represent?

I believe the first answer is correct. File is closed after first x loop in the original example.
Yes.  8)
Title: Re: File not open??? Why?
Post by: OC DelGuy on January 31, 2023, 08:38:51 am
Try not to close the file in your loop, does it help?
Code: Pascal  [Select][+][-]
  1. Procedure WriteVillagedata;   // This will write the Data Structure to file.
  2.   Var
  3.     x, y : Integer;
  4.     FilenameOut: TextFile;
  5.   Begin
  6.     Assignfile(FilenameOut, 'VillageData.txt');
  7.     Try
  8.       ReWrite(FilenameOut);
  9.       For x := 1 to recds do
  10.         Begin
  11.           WriteLn(FilenameOut, Villages[x].Name);            This is line 60 as referred to in the error message.
  12.           WriteLn(FilenameOut, Villages[x].Inn);
  13.           WriteLn(FilenameOut, Villages[x].Government);
  14.           WriteLn(FilenameOut, Villages[x].Population);
  15.           WriteLn(FilenameOut, Villages[x].Families);
  16.           WriteLn(FilenameOut, Villages[x].Farmers);
  17.           WriteLn(FilenameOut, Villages[x].Artisans);
  18.           WriteLn(FilenameOut, Villages[x].Laborers);
  19.           WriteLn(FilenameOut, Villages[x].Paupers);
  20.           For y := 1 to 3 do
  21.             Begin
  22.               WriteLn(FilenameOut, Villages[x].Gods[y]);
  23.               WriteLn(FilenameOut, Villages[x].Taverns[y]);
  24.               WriteLn(FilenameOut, Villages[x].Trade[y]);
  25.             end; {For y}
  26.         End; {For x}
  27.     finally
  28.       Close(FilenameOut);
  29.     end; {Try}
  30.   end; {Proc WriteVillagedata}

Just seeing this, I'm pretty sure that's the problem.  This is one of those BRAIN-FART instances.  I just didn't notice it.  If I had noticed it before, I would not have posted this.  Of course it should be outside the loop, and that explains the runtime error.  It has to be happening during the second iteration of the x loop.  I'm on my Chrome book now, but I'll be back on the MSI tomorrow.
Title: Re: File not open??? Why?
Post by: OC DelGuy on January 31, 2023, 08:57:42 am
The above works, @KodeZwerg likely caught the problem, the close file being in the loop.
Yes.  I haven't checked it out, but I'm willing to bet it's the Close in the loop.  I'm also willing to bet that the runtime error is happening during the second iteration of the x loop.  Sorry guys, I just didn't notice.  I had a BRAIN-FART!!  When I check it tomorrow, I'm sure that will be the problem.
Title: Re: File not open??? Why?
Post by: OC DelGuy on January 31, 2023, 09:05:37 am
Maybe also his "FilenameOut" is wrong, since he not show, I added that on my own as local.
No, I don't believe so.  FilenameIn and FilenameOut are both declared as global variables.
Title: Re: File not open??? Why?
Post by: KodeZwerg on January 31, 2023, 09:20:48 am
Maybe also his "FilenameOut" is wrong, since he not show, I added that on my own as local.
No, I don't believe so.  FilenameIn and FilenameOut are both declared as global variables.
I believe that you did, its just the question as what  :-\
Title: Re: File not open??? Why?
Post by: OC DelGuy on January 31, 2023, 09:22:36 am
Yup, something like that (missing exception handling, though?)
Uhm... the only "error handling" that comes in my mind would be to test if file exists, try to delete, when that succeed write it.
Do you have something different in your mind that I am currently not aware of?
Or you meant a seperate "try/except" around the SaveToFile() ?
As longer I think about, as more strange stuff come in my head  %) (I usual just let the class do the job...)

And of course  ;D count from zero  :D
Absolute! Thats why I noted:
Ofc the record stuff I can't check but at least you see some logic.
( Where I actual meant an array  :-[  :-X  :P )

There's no error handling because my error is placing the close inside the loop.  But that's because I first worked on the loop and then decided to put in the close.  I just clicked after the "WriteLn(FilenameOut" stuff andthe loop.  I forgot to make sure it was outside BOTH loops.

I surely wasn't thinking of IfFileExists, because the ReWrite(FilenameOut) takes care of that.  I would've used that in the GetFileLines because that one uses the Reset(FilenameIn).  It's not really error checking, but I'd get a "File Not Found" runtime error from the Reset function.
Title: Re: File not open??? Why? Because I had a BRAIN-FART! :D :D
Post by: OC DelGuy on January 31, 2023, 06:58:45 pm
Yep, done.  Moved the Close outside the loop and now I have a properly formatted Data file.

The End
TinyPortal © 2005-2018