Board index » delphi » Passing file variable to Function

Passing file variable to Function

I can't get my function to work:

Function FetchLine(var CFile:file):Boolean;
 var
   TmpChar:Array[1..2] of Char;
   EndRead:Boolean;
 begin
   FLength:=0;
   EndRead:=False;
   FetchLine:=False;
   repeat
    BlockRead(CFile,TmpChar,1,NumRead);
    Writeln(TmpChar[1]); {here for debugging}
    If (TmpChar[1]<>#13) and (TmpChar[1]<>#10) and (NumRead>0) then
                  begin
                    Inc(FLength);
                    FBuff[FLength]:=TmpChar[1];
                    Writeln('Length=',FLength);  {here for debugging}
                  end;
    If (TmpChar[1]=#13) or (TmpChar[1]=#10) then
          begin
           EndRead:=True;
           FetchLine:=True;
          end;
    If (NumRead=0) or (FLength>=SizeOf(FBuff)) then EndRead:=True;
   until EndRead;
 end;

It is begin called with:
     Assign(DescFile,D+'DESCRIPT.ION');
     Reset(DescFile);
      TmpStr:='';
      While FetchLine(DescFile) and (UCASEStr(TmpStr)<>DirInfo.Name) do
        begin
          If FLength>100 then
              A:=CA2Str(1,100)
             else
              A:=CA2Str(1,FLength);
          TmpStr:=Copy(A,1,Pos(' ',A)-1);
        end;
     Close(DescFile);

The problem is that the FetchLine function locks up after nearly
finishing adding the first character from the file.  Why I don't know.

HELP?

--
Jeff Patterson  --  Fredericton Area Network

 

Re:Passing file variable to Function


AA>I can't get my function to work:

AA>Function FetchLine(var CFile:file):Boolean;
AA> var
AA>   TmpChar:Array[1..2] of Char;
AA>   EndRead:Boolean;
AA> begin
AA>   FLength:=0;
AA>   EndRead:=False;
AA>   FetchLine:=False;
AA>   repeat

      <code snipped>

AA>   until EndRead;
AA> end;

I didn't look at your complete code, but a suggestion for avoiding
problems when reading a file within a loop is to use a WHILE/DO loop
rather than a REPEAT/UNTIL. The reason is that the latter will always
execute at least once, and so if the file is empty it will read past the
end of the file, causing problems.

        -- Kim Forwood --

  /-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-\
  $           Kim Forwood  <kim.forw...@access.cn.camriv.bc.ca>          %
  %         For what purpose is life, if one cannot live freely?         $
  \-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-/

Re:Passing file variable to Function


In article <Pine.SOL.3.91.960403201205.29198B-100...@fan1.fan.nb.ca>

Quote
Jeff Patterson wrote:

>I can't get my function to work:

Neither can anyone else.  Jeff, the sample you loaded is full of
typoes, syntax errors, and type mismatches.  There is so little here,
we can only guess what it is all about.  For example, Reset(DescFile)
implies that it is a Text file, but is passed as an untyped file.  The
program appears to use a lot of global variables, not of which you
supplied, etc.

The first thing that caught my eye is entering into a file read with a
repeat loop.  Wouldn't be too bad, except the test foe an eof condition
is made at he end of the loop.  There is a lot of code that is being
executed even if you read nothing!

I almost {*word*88}d when I saw that you were reading an untyped file one
character at a time.  This really isn't an error and I try not to
critize the base design but this one took my breath away.  If you're
trying to create a sloooow program, you are on the right track. :)

If you want to read one character at a time without the work of
buffering the input, I suggest that you use a text file.  At least by  
default it buffers 128 characters.

You need to re-think what you are doing.  A repeat loop executes once,
so if the file is empty, you're cooked!  That's why you see most code
using a while loop for reading files.

Quote

>Function FetchLine(var CFile:file):Boolean;
> var
>   TmpChar:Array[1..2] of Char;
>   EndRead:Boolean;
> begin
>   FLength:=0;
>   EndRead:=False;
>   FetchLine:=False;
>   repeat
>    BlockRead(CFile,TmpChar,1,NumRead);
>    Writeln(TmpChar[1]); {here for debugging}
>    If (TmpChar[1]<>#13) and (TmpChar[1]<>#10) and (NumRead>0) then

Put your most critical test first. in this case NumRead>0, it is false
then TmpChar[1] is undefined and need not be tested at all.
Quote
>                  begin
>                    Inc(FLength);
>                    FBuff[FLength]:=TmpChar[1];
>                    Writeln('Length=',FLength);  {here for debugging}
>                  end;
>    If (TmpChar[1]=#13) or (TmpChar[1]=#10) then

this staement resumes work on TmpChar without regard to whether it is
valid.  What if NumRead is zero?  You'd be looking at old garbage!
Quote
>          begin
>           EndRead:=True;
>           FetchLine:=True;
>          end;
>    If (NumRead=0) or (FLength>=SizeOf(FBuff)) then EndRead:=True;

This needs to be near the top of the loop.  If NumRead is zero, there is
no input for this routine to process.  This is the number of records
that were read.  If none were read, you have some type of physical error
(usually reading past the end of the file).  Once it happens it doesn't
usually change.

Quote
>   until EndRead;
> end;

>It is begin called with:
>     Assign(DescFile,D+'DESCRIPT.ION');
>     Reset(DescFile);
>      TmpStr:='';
>      While FetchLine(DescFile) and (UCASEStr(TmpStr)<>DirInfo.Name) do
>        begin
>          If FLength>100 then
>              A:=CA2Str(1,100)
>             else
>              A:=CA2Str(1,FLength);
>          TmpStr:=Copy(A,1,Pos(' ',A)-1);
>        end;
>     Close(DescFile);

>The problem is that the FetchLine function locks up after nearly
>finishing adding the first character from the file.  Why I don't know.

>HELP?

>--
>Jeff Patterson  --  Fredericton Area Network

I'm not sure why you feel you have to go throught all this heart ache to
read lines from an untyped file when it looks like a simple text file
would do nicely.  Any particular reason?

                      ...red

Knowledge is one of the few things that you
can give away and still keep for yourself.

Re:Passing file variable to Function


Quote
Jeff Patterson (aa...@fan.nb.ca) wrote:
>I can't get my function to work:
>Function FetchLine(var CFile:file):Boolean;
[...]
>   repeat
>    BlockRead(CFile,TmpChar,1,NumRead);

[...]

Quote
>It is begin called with:
>     Assign(DescFile,D+'DESCRIPT.ION');
>     Reset(DescFile);

      ^^^^^^^^^^^^^^^
Must be Reset(DescFile,1).
There may be other errors, but this is the first.

The fact that untyped file has an undefined record size must be added
to manuals in BIG AND FAT letters, as well as to all the FAQ's on
Turbo Pascal and derivatives.

--
Zhenya Sorokin

E-mail     : soro...@ps1.iaee.tuwien.ac.at, s...@rs6.iaee.tuwien.ac.at
Paper-mail : E. Sorokin, Gusshausstr. 27/359-4, 1040 Vienna, Austria
Voice-mail : +43(1)58801-3703, -3948
Fax-mail   : +43(1)504 2477

Re:Passing file variable to Function


On 3 Apr 1996, Kim Forwood wrote:

Quote

> AA>I can't get my function to work:

> AA>Function FetchLine(var CFile:file):Boolean;
> AA> var
> AA>   TmpChar:Array[1..2] of Char;
> AA>   EndRead:Boolean;
> AA> begin
> AA>   FLength:=0;
> AA>   EndRead:=False;
> AA>   FetchLine:=False;
> AA>   repeat

>       <code snipped>

> AA>   until EndRead;
> AA> end;
> I didn't look at your complete code, but a suggestion for avoiding
> problems when reading a file within a loop is to use a WHILE/DO loop
> rather than a REPEAT/UNTIL. The reason is that the latter will always
> execute at least once, and so if the file is empty it will read past the
> end of the file, causing problems.

I had it before, but every occurance of the EOF command locked up the
computer.  

Re:Passing file variable to Function


Quote
On Thu, 4 Apr 1996, R. E. Donais wrote:

> In article <Pine.SOL.3.91.960403201205.29198B-100...@fan1.fan.nb.ca>
> Jeff Patterson wrote:

> >I can't get my function to work:
> Neither can anyone else.  Jeff, the sample you loaded is full of
> typoes, syntax errors, and type mismatches.  There is so little here,

Then it must have been from posting because it compiled no problem.

Quote
> we can only guess what it is all about.  For example, Reset(DescFile)
> implies that it is a Text file, but is passed as an untyped file.  The
> program appears to use a lot of global variables, not of which you
> supplied, etc.

I didn't bother including them no, because i can't see how they would
cause the computer to lock up.   All files have been defined as "file",
untyped.

Quote

> The first thing that caught my eye is entering into a file read with a
> repeat loop.  Wouldn't be too bad, except the test foe an eof condition
> is made at he end of the loop.  There is a lot of code that is being
> executed even if you read nothing!

Took out EOF() checks because they were locking up the computer before it
even got to the loop.

Quote
> I almost {*word*88}d when I saw that you were reading an untyped file one
> character at a time.  This really isn't an error and I try not to
> critize the base design but this one took my breath away.  If you're
> trying to create a sloooow program, you are on the right track. :)

Only way I can figure out how to read a text file since no one in this
newsgroup helped me with such after posting twice.  I'll try to read it in
with larger blocks when/if I ever figure out how, but as far as I can tell
that will take about 1000 lines of code because I guess I would need to
including Seeking over and over, and have to keep track more of where I
am in the file.

Quote
> If you want to read one character at a time without the work of
> buffering the input, I suggest that you use a text file.  At least by  
> default it buffers 128 characters.

Can't use "text" for two reasons.  1) it doesn't do much of anything for
text around 511 bytes in length.   2) It won't read files without #13's
in it at all.

Quote
> You need to re-think what you are doing.  A repeat loop executes once,
> so if the file is empty, you're cooked!  That's why you see most code
> using a while loop for reading files.

Perhaps if it wouldn't lock up.

Quote
> >The problem is that the FetchLine function locks up after nearly
> >finishing adding the first character from the file.  Why I don't know.

> I'm not sure why you feel you have to go throught all this heart ache to
> read lines from an untyped file when it looks like a simple text file
> would do nicely.  Any particular reason?

Mentioned above, line lengths, and EOL markers.    I can't find any code
to do such, so I'm just trying to throw whatever works together (I
currently wouldn't even mind if it only processed 30 characters a second,
I just want it to DO something).

Thanks for pointing things out though.

Re:Passing file variable to Function


Re:Passing file variable to Function


Problem solved.   Thanks for the advice to all that replied.

Quote
On Thu, 4 Apr 1996, R. E. Donais wrote:
> >It is begin called with:
> >     Assign(DescFile,D+'DESCRIPT.ION');
> >     Reset(DescFile);

I changed that Reset(DescFile);  to Reset(DescFile,1) and it instantly
worked and stopped locking up the computer.   (odd how it read one
character still with BlockRead without locking up though).

Re:Passing file variable to Function


Re:Passing file variable to Function


AA>On Thu, 4 Apr 1996, R. E. Donais wrote:

AA>> we can only guess what it is all about.  For example, Reset(DescFile)
AA>> implies that it is a Text file, but is passed as an untyped file.  The
AA>> program appears to use a lot of global variables, not of which you
AA>> supplied, etc.

AA>I didn't bother including them no, because i can't see how they would
AA>cause the computer to lock up.   All files have been defined as "file",
AA>untyped.

For proper analysis of a problem, it's important to include *all*
information pertaining to the given problem, in order to properly
determine that it isn't part of the problem.

AA>> The first thing that caught my eye is entering into a file read with a
AA>> repeat loop.  Wouldn't be too bad, except the test foe an eof condition
AA>> is made at he end of the loop.  There is a lot of code that is being
AA>> executed even if you read nothing!

AA>Took out EOF() checks because they were locking up the computer before it
AA>even got to the loop.

A very bad reason. I would imagine that your use (or mis-use) of EOF was
at least part of the problem to begin with.

AA>> I almost {*word*88}d when I saw that you were reading an untyped file one
AA>> character at a time.  This really isn't an error and I try not to
AA>> critize the base design but this one took my breath away.  If you're
AA>> trying to create a sloooow program, you are on the right track. :)

AA>Only way I can figure out how to read a text file since no one in this
AA>newsgroup helped me with such after posting twice.  I'll try to read it in
AA>with larger blocks when/if I ever figure out how, but as far as I can tell
AA>that will take about 1000 lines of code because I guess I would need to
AA>including Seeking over and over, and have to keep track more of where I
AA>am in the file.

Have patience. Not everyone that is capable or willing to take the time
to help can respond immediately. It also helps to present the problem
clearly, showing that you've put some thought into it already (not
saying that you didn't). Have a look at BlockRead/BlockWrite if you
haven't yet.

AA>> You need to re-think what you are doing.  A repeat loop executes once,
AA>> so if the file is empty, you're cooked!  That's why you see most code
AA>> using a while loop for reading files.

AA>Perhaps if it wouldn't lock up.

If it's locking up then there is something wrong with your code. It's
guaranteed that a REPEAT/UNTIL loop will eventually cause problems down
the road.

        -- Kim Forwood --

  /-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-\
  $           Kim Forwood  <kim.forw...@access.cn.camriv.bc.ca>          %
  %         For what purpose is life, if one cannot live freely?         $
  \-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-/

Re:Passing file variable to Function


On 4 Apr 1996, Kim Forwood wrote:

Quote
> AA>Took out EOF() checks because they were locking up the computer before it
> AA>even got to the loop.

> A very bad reason. I would imagine that your use (or mis-use) of EOF was
> at least part of the problem to begin with.

Well it was the only problem I had (wasn't mis-use).  Problem was Reset().

Quote
> Have patience. Not everyone that is capable or willing to take the time
> to help can respond immediately. It also helps to present the problem
> clearly, showing that you've put some thought into it already (not
> saying that you didn't). Have a look at BlockRead/BlockWrite if you
> haven't yet.

Was weeks patient enough?     That doesn't mean I wasn't still waiting
for an answer.   I do try to learn on my own.   I use
BlockRead/BlockWrite all the time.   I have a 64 K of source code for the
program this is in.  I wrote another program before that contains 52K of
source with a fossil interface i wrote myself.   I just still can't
figure out how to parse out the lines from a BlockRead.  What do you do
if it the line (or EOL) ventures past the current buffer you read.

Quote
> AA>Perhaps if it wouldn't lock up.

> If it's locking up then there is something wrong with your code. It's
> guaranteed that a REPEAT/UNTIL loop will eventually cause problems down
> the road.

It was the Reset that was locking things up later on.   Since I can now
use EOF again, i have removed Repeat Until and switched to While/begin..end.

Re:Passing file variable to Function


Hello Jeff,
    Up to the time of my writing this I haven't seen any direct solution
to your initial question. If I have missed a posting, please disregard
this one.

    First off, it appears you want to scan the file character by character.
Thus use a blocksize of 1 or else Borland Pascal will default to 128
char blocks during blockread/write:

   { example code }
   var
       DescFile : File;
   ...

   Assign(DescFile,D+'DESCRIPT.ION');
   Reset(DescFile,1);   { use blocksize 1 for untyped files }

   ...

   { end example code }

    I believe the blockread of length 1 in your code was destroying the
stack and who knows what else by reading 128 chars into TmpChar which
only has a size of 2 bytes. Good luck.

Ray

In article <Pine.SOL.3.91.960403201205.29198B-100...@fan1.fan.nb.ca>,

Quote
Jeff Patterson <aa...@fan.nb.ca> wrote:

>I can't get my function to work:

>Function FetchLine(var CFile:file):Boolean;
> var
>   TmpChar:Array[1..2] of Char;
>   EndRead:Boolean;
> begin
>   FLength:=0;
>   EndRead:=False;
>   FetchLine:=False;
>   repeat
>    BlockRead(CFile,TmpChar,1,NumRead);
>    Writeln(TmpChar[1]); {here for debugging}
>    If (TmpChar[1]<>#13) and (TmpChar[1]<>#10) and (NumRead>0) then
>                  begin
>                    Inc(FLength);
>                    FBuff[FLength]:=TmpChar[1];
>                    Writeln('Length=',FLength);  {here for debugging}
>                  end;
>    If (TmpChar[1]=#13) or (TmpChar[1]=#10) then
>          begin
>           EndRead:=True;
>           FetchLine:=True;
>          end;
>    If (NumRead=0) or (FLength>=SizeOf(FBuff)) then EndRead:=True;
>   until EndRead;
> end;

>It is begin called with:
>     Assign(DescFile,D+'DESCRIPT.ION');
>     Reset(DescFile);
>      TmpStr:='';
>      While FetchLine(DescFile) and (UCASEStr(TmpStr)<>DirInfo.Name) do
>        begin
>          If FLength>100 then
>              A:=CA2Str(1,100)
>             else
>              A:=CA2Str(1,FLength);
>          TmpStr:=Copy(A,1,Pos(' ',A)-1);
>        end;
>     Close(DescFile);

>The problem is that the FetchLine function locks up after nearly
>finishing adding the first character from the file.  Why I don't know.

>HELP?

>--
>Jeff Patterson  --  Fredericton Area Network

--
 ________________________________________________________________
| "Even a fool is thought wise if he keeps silent,  (Prov 17:28)
|   and discerning if he holds his tongue."    ral...@netcom.com

Re:Passing file variable to Function


Re:Passing file variable to Function


Quote
Jeff Patterson wrote:
>Only way I can figure out how to read a text file since no one in this
>newsgroup helped me with such after posting twice.  I'll try to read it in
>with larger blocks when/if I ever figure out how, but as far as I can tell
>that will take about 1000 lines of code because I guess I would need to
>including Seeking over and over, and have to keep track more of where I
>am in the file.

Jeff, I just started reading this group so I never saw you original message
  asking for help on reading textfiles using blockread and blockrite.

Heres a stratigy I use on reading straight text with CR/LF (#13#10) line
delimiters.

{ Return a text string to caller }
Fucntion ReadFLN(Var F:File) :String;
Var
  I
  BtsRead : Integer;
  StrRead : String;                 { Var so read/buffer string to                                 }
  FPOs    : Longint;                { Current file Position Var                                    }
Begin
  S := '';
  If Not(EOF(F)) Then               { Just a little caution here }
  Begin
    FPos := FilePos(F);             { Set Up for "Quiet" read                                      }
    Blockread(F,S[1],255,BtsRead);  { 3 things here 1.) No Big error if less than 255 bytes read   }
                                    {               2.) read MAX a String will hold.               }
                                    {               3.) Read DIRECTLY into our variable            }
    S[0] := Char(BtsRead);          { Set inital string length to number of bytes read             }
    I := POS(#13,S);                { Use Pos to search for #13 (CR) first delim.                  }
    If I > 0 Then
      S[0] := Char(I-1);            { Set string length to search results                          }
    { Heres the "Quiet" part }
    Seek(F,FPos);                   { Reset Filepointer to inital/entry position                   }
  End;
  ReadFLn := S;                     { Return results                                               }
End;

There a MUCH better ways of doing this job, but this one should give you a starting place.  
This Routine will be much faster, on average, than reading one chatacter at a time.  
A footnote her would have to be with tracking the File Cursor/pointer.  To read the next string,
Adjust the next seek loaction to the length of the returned string.  I think this will do in a
pinch.

James D Oldroyd

Re:Passing file variable to Function


Go to page: [1] [2]

Other Threads