Lazarus

Programming => General => Topic started by: oproescu on February 12, 2019, 01:32:38 pm

Title: Read statement in Lazarus
Post by: oproescu on February 12, 2019, 01:32:38 pm
How can I read a text file character by character? I tried with

      assignfile(file1,texte);reset(file1);   
         repeat
         read(file1,s);         
         until eof(file1);
      closefile(file1);

The identifier s gets the value of a whole row and after the first row is read, the application locks like in a closed loop between repeat and until. In Delphi run well, but I need this in Lazarus.
Thanks for your help!
Title: Re: Read statement in Lazarus
Post by: marcov on February 12, 2019, 01:49:50 pm
Change the repeat to a while, iow always check eof before reading.

Change the type of s to a char instead of a string.

Always create a complete, compiling example. Doing otherwise requires a lot of guesswork.
Title: Re: Read statement in Lazarus
Post by: Handoko on February 12, 2019, 02:05:45 pm
Something like this:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Memo1: TMemo;
  17.     procedure Button1Click(Sender: TObject);
  18.   end;
  19.  
  20. var
  21.   Form1: TForm1;
  22.  
  23. implementation
  24.  
  25. {$R *.lfm}
  26.  
  27. { TForm1 }
  28.  
  29. procedure TForm1.Button1Click(Sender: TObject);
  30. const
  31.   FileName = 'testfile.txt';
  32. var
  33.   FileInput : File of Char;
  34.   C         : Char;
  35. begin
  36.  
  37.   Button1.Visible := False;
  38.   Memo1.Visible   := True;
  39.   Memo1.Clear;
  40.  
  41.   {$I+}
  42.   AssignFile(FileInput, FileName);
  43.   try
  44.     Reset(FileInput);
  45.     while not(EOF(FileInput)) do
  46.     begin
  47.       Read(FileInput, C);
  48.       Memo1.Text := Memo1.Text + C;
  49.     end;
  50.     CloseFile(FileInput);
  51.   except
  52.     on E: EInOutError do
  53.       ShowMessage('Error: ' +  E.ClassName + '/' + E.Message);
  54.   end;
  55.  
  56. end;
  57.  
  58. end.

Title: Re: Read statement in Lazarus
Post by: lucamar on February 12, 2019, 02:49:35 pm
With Text (or TextFile), Read() stops at the first end-of-line and can't keep going until you consume it (see "difference between read and readLn (http://wiki.freepascal.org/Read#difference_between_read_and_readLn) in the wiki).

If you really want to read character by character do it like p.e.:
Code: Pascal  [Select][+][-]
  1.   Assign(AFile, AFileName);
  2.   Reset(AFile);
  3.   while not EOF(AFile) do begin
  4.     if EOLn(AFile) then
  5.       ReadLn(AFile)
  6.     else begin
  7.       Read(AFile, AChar);
  8.       DoWhateverWith(AChar);
  9.     end;
  10.   end;
  11.   Close(AFile)

Or simply declare your file as:
Code: Pascal  [Select][+][-]
  1. var
  2.   AFile: file of char;
and read it normally.
Title: Re: Read statement in Lazarus
Post by: jamie on February 12, 2019, 11:12:47 pm
I think an IoResult somewhere is in order, too!
Title: Re: Read statement in Lazarus
Post by: PascalDragon on February 13, 2019, 10:30:40 am
I think an IoResult somewhere is in order, too!
Only if you use {$I-}. Otherwise exceptions will be thrown right away. See also here (https://www.freepascal.org/docs-html/current/prog/progsu38.html#x45-440001.2.38).
Title: Re: Read statement in Lazarus
Post by: oproescu on February 15, 2019, 09:00:11 am
I'm coming back late.
Thanks, the two changes (repeat replaced with while and s declared char instead of string) go fine!
I wish you a good day!

Oproescu
TinyPortal © 2005-2018