Board index » delphi » prompted read in WHILE not eof loop

prompted read in WHILE not eof loop

This may be covered in a FAQ.  If so, telling me how to find the FAQ would
be much appreciated!

Here are the questions:

1.)  A loop such as

  while not eof do begin
     write('enter an integer: ');
     read(n);
     sum:=sum+n;
  end;

Actually writes prompts to the screen AFTER the read is executed????
I'm confused about why this happens.  Apparently, its the use of eof
that causes the trouble.  A WHILE (or more likely, a REPEAT ... UNTIL)
loop that watches for a sentinel value does does not exhibit this behavior.

2.)  In the loop above, under Turbo Pascal for Windows, eof doesn't seem
to every be satisfied.  However, under VAX/VMS pascal, one can enter
the last integer input with <control>-Z instead of return.  eof(input) will
be set to true, and the loop terminates.   Is there a way to signal eof
to TPW?

 

Re:prompted read in WHILE not eof loop


Quote
> This may be covered in a FAQ.  If so, telling me how to find the FAQ would
> be much appreciated!

> Here are the questions:

> 1.)  A loop such as

>   while not eof do begin
>      write('enter an integer: ');
>      read(n);
>      sum:=sum+n;
>   end;

> Actually writes prompts to the screen AFTER the read is executed????
> I'm confused about why this happens.  Apparently, its the use of eof
> that causes the trouble.  A WHILE (or more likely, a REPEAT ... UNTIL)
> loop that watches for a sentinel value does does not exhibit this behavior.

   This is due to the "read" you're using.  Although this behavior is not
intuitive, the TP/BP RTL and the buffering of the input buffer causes
your situation.  It will be solved when you change the "read" to
"readln".

Quote

> 2.)  In the loop above, under Turbo Pascal for Windows, eof doesn't seem
> to every be satisfied.  However, under VAX/VMS pascal, one can enter
> the last integer input with <control>-Z instead of return.  eof(input) will
> be set to true, and the loop terminates.   Is there a way to signal eof
> to TPW?

   That's because there is no "EOF" in the input stream of data you're
processing - "EOF" applies to files.  I suggest you look for some other
method of terminating your input data/information, such as some sentinel
value, a negative number, etc.  IMHO, a Repeat loop might handle all this
better...

Re:prompted read in WHILE not eof loop


In article <MPG.eb666d7563ab547989...@news.primenet.com>,

Quote
mrc...@primenet.com (Mike Copeland) writes:
>Subject:    Re: prompted read in WHILE not eof  loop
>From:       mrc...@primenet.com (Mike Copeland)
>Date:21 Oct 1997 07:17:03 -0700

>> ...
>>   while not eof do begin
>>      write('enter an integer: ');
>>      read(n);
>>      sum:=sum+n;
>>   end;

>> [This loop] writes prompts to the screen AFTER the read is executed.
>> I'm confused about why this happens.  . . .

>   This is due to the "read" you're using.  Although this behavior is not
>intuitive, the TP/BP RTL and the buffering of the input buffer causes
>your situation.  It will be solved when you change the "read" to
>"readln".

>> 2.)  In the loop above, under Turbo Pascal for Windows, eof doesn't seem
>> to ever be satisfied.  . . .

>   That's because there is no "EOF" in the input stream of data you're
>processing - "EOF" applies to files.  . . .

Hmm...  I see I wasn't clear.  I wrote this little example to _illustrate_
something I stumbled across while writing a "real" program.  I had a WHILE
not EOF(filename) loop, in a driver which was to (eventually) do I/O to
a disk file.  I stuck in the prompts, and popped-out the file name just to
help
with testing from the console.  That's when I ran across the problem.  Of
course,
disk files were accessed when the project was completed, so no more problems.

However, I still want to _understand_  why the program behaves the way it
does.  By the way, I am not (usually) programming in either Pascal or
Windows (which is no doubt painfully obvious already).  So I don't understand
how buffering input screws-up the output.  I suppose that IS my question.

Now I've tried, as Mr. Copeland suggests, changing the READ to a READLN.
Here are the results:  

*  on VAX/VMS Pascal, no difference whatever.  

* On TPW, it is different, but now either a second data item must be entered
after the first is read (which is just thrown away) or two returns must be
typed
after _each_and_every_ integer_  is entered.

Whoa ... I thought I was confused before!

Finally, with respect to eof(input), is it true that TPW treats INPUT in a
fundamentally different way from, say, a disk file?  This is not true,
for instance, of DEC's Pascal on VAX/VMS.  You can signal eof(input)
easily by terminating a string with <control>-Z.  

But, even with a valid EOF for INPUT, VAX Pascal exhibits (apparently)
strange behavior on these loops.

Can anybody clue me in on what's happening here?

Thanks in advance for whatever insight you can offer.

Re:prompted read in WHILE not eof loop


In article <19971022043300.AAA27...@ladder01.news.aol.com>,

Quote
TSprague2 <tsprag...@aol.com> wrote:
>In article <MPG.eb666d7563ab547989...@news.primenet.com>,
>mrc...@primenet.com (Mike Copeland) writes:

>>Subject:        Re: prompted read in WHILE not eof  loop
>>From:   mrc...@primenet.com (Mike Copeland)
>>Date:21 Oct 1997 07:17:03 -0700

>>> ...
>>>   while not eof do begin
>>>      write('enter an integer: ');
>>>      read(n);
>>>      sum:=sum+n;
>>>   end;

>>> [This loop] writes prompts to the screen AFTER the read is executed.
>>> I'm confused about why this happens.  . . .

>>   This is due to the "read" you're using.  Although this behavior is not
>>intuitive, the TP/BP RTL and the buffering of the input buffer causes
>>your situation.  It will be solved when you change the "read" to
>>"readln".

>>> 2.)  In the loop above, under Turbo Pascal for Windows, eof doesn't seem
>>> to ever be satisfied.  . . .

>>   That's because there is no "EOF" in the input stream of data you're
>>processing - "EOF" applies to files.  . . .

>Hmm...  I see I wasn't clear.  I wrote this little example to _illustrate_
>something I stumbled across while writing a "real" program.  I had a WHILE
>not EOF(filename) loop, in a driver which was to (eventually) do I/O to
>a disk file.  I stuck in the prompts, and popped-out the file name just to
>help
>with testing from the console.  That's when I ran across the problem.  Of
>course,
>disk files were accessed when the project was completed, so no more problems.

>However, I still want to _understand_  why the program behaves the way it
>does.

It is simple. Eof is true at the physical end of the file or when the
user presses ^Z. How can the program know if user presses ^Z. It simply
has to wait and see what the user types. So calling eof pauses the
program and waits the user to type a line. I do not know why it works in
VAX Pascal but I have noticed some differences on how console IO is
handled on different systems.

The solution? Since eof can potentially pause the program you must call
it only after the prompting and before read.

var n,sum:integer;
    flag:boolean;

begin

  sum:=0;
  flag:=false;
  repeat
     write('enter an integer: ');
     if not eof then begin
       readln(n);
       sum:=sum+n;
       writeln(n,' ',sum)
     End
     else flag:=true;
  until flag;
end.

Alternatively you could prompt just before the loop and second time at
the end of the loop before eof-test.

Lets get back into your original code:

  while not eof do begin
     write('enter an integer: ');
     read(n);
     sum:=sum+n;
  end;

If we wanted that to execute in some rational way then the computer
should react to the ^Z after it has read a number and added it. The only
way it can do this is by pausing at eof. If it only pauses at read(),
then the read will fail when the user types ^Z.

Quote
>  By the way, I am not (usually) programming in either Pascal or
>Windows (which is no doubt painfully obvious already).  So I don't understand
>how buffering input screws-up the output.  I suppose that IS my question.

>Now I've tried, as Mr. Copeland suggests, changing the READ to a READLN.
>Here are the results:  

>*  on VAX/VMS Pascal, no difference whatever.  

>* On TPW, it is different, but now either a second data item must be entered
>after the first is read (which is just thrown away) or two returns must be
>typed
>after _each_and_every_ integer_  is entered.

Yes, because there is nothing in the buffer after readln it always
pauses at eof. Actually you do not need to press enter twice. You could
enter the number when the program pauses at eof.

Quote

>Whoa ... I thought I was confused before!

>Finally, with respect to eof(input), is it true that TPW treats INPUT in a
>fundamentally different way from, say, a disk file?

No (apart from the fact that a disk file has a physical end and input
stream does not, so in input stream ^Z is the only end). The fact that
they are treated in the same way is the thing that causes confusion. IN
file there is no pausing as the next character is always available. In
console it is only when the user has pressed enter to send a line to the
buffer.

Quote
>  This is not true,
>for instance, of DEC's Pascal on VAX/VMS.  You can signal eof(input)
>easily by terminating a string with <control>-Z.  

>But, even with a valid EOF for INPUT, VAX Pascal exhibits (apparently)
>strange behavior on these loops.

Because your code is not valid. Or to make it simple you prompt at the
wrong place. (Note that with file IO there is no need to prompt)

Quote
>Can anybody clue me in on what's happening here?

>Thanks in advance for whatever insight you can offer.

Note that in some systems readln() also behaves strangely. In those
systems with input pointers the input pointer (input^) points to the
next character to be read. In console IO this is unknown after readln
until the user presses enter on the next line. Probably for this reason
Borland got rid of the file pointers. Pascal console IO is not easy.

Osmo

Re:prompted read in WHILE not eof loop


 ts> However, I still want to _understand_  why the program behaves the way
 ts> it does. By the way, I am not (usually) programming in either Pascal
 ts> or Windows (which is no doubt painfully obvious already). So I don't
 ts> und how buffering input screws-up the output. I suppose that IS my
 ts> questi

 ts> But, even with a valid EOF for INPUT, VAX Pascal exhibits (apparently)
 ts> strange behavior on these loops.

 ts> Can anybody clue me in on what's happening here?

I believe what it happens is:

DEC's pascal reads from the console itself.  I am sure if you wrote a program
that displays two lines of text, you could pipe it:

textprog > output.txt

However, using writeln, you _cannot_ pipe it two a file.

It (turbo pascal) doesn't do it that way.  however, if you assign the console
to a file, I believe it'll work like you want it to:

program readfromconsole;
var
  console:text;
  inputtext:string;

begin
  assign(console,'');
  rewrite(console);
  while not eof(console) do
    readln(console,inputtext);
  writeln(console,'this can be piped into a file!');
  close(console);
end.

this method also works if you want to use the ansi driver to display ansi
codes.

the maverick - m...@microserve.net - http://xf.home.ml.org

... The word 'meaningful' when used today is nearly always meaningless.

Re:prompted read in WHILE not eof loop


In article <fa4_9710240...@rebelx.microserve.com>,

Quote
the maverick <the.maveric...@rebelx.microserve.com> wrote:
> ts> However, I still want to _understand_  why the program behaves the way
> ts> it does. By the way, I am not (usually) programming in either Pascal
> ts> or Windows (which is no doubt painfully obvious already). So I don't
> ts> und how buffering input screws-up the output. I suppose that IS my
> ts> questi

> ts> But, even with a valid EOF for INPUT, VAX Pascal exhibits (apparently)
> ts> strange behavior on these loops.

> ts> Can anybody clue me in on what's happening here?

>I believe what it happens is:

>DEC's pascal reads from the console itself.  I am sure if you wrote a program
>that displays two lines of text, you could pipe it:

>textprog > output.txt

That has nothing to do with pipes. Pipe is a way of connecting two
processes to that the output of one goes as the input of the other.
Pipes therefore require always multitasking. (MS-Dos attempts to
simulate the way pipes are used in UNIX with temporary files, but this
is not actually a pipe)

Quote

>However, using writeln, you _cannot_ pipe it two a file.

>It (turbo pascal) doesn't do it that way.  however, if you assign the console
>to a file, I believe it'll work like you want it to:

There is no need to open any console. One can just use writeln as output
is normally defined as standard output. (Of course if you use CRT then
things are different)

- Show quoted text -

Quote
>program readfromconsole;
>var
>  console:text;
>  inputtext:string;

>begin
>  assign(console,'');
>  rewrite(console);
>  while not eof(console) do
>    readln(console,inputtext);
>  writeln(console,'this can be piped into a file!');
>  close(console);
>end.

>this method also works if you want to use the ansi driver to display ansi
>codes.

>the maverick - m...@microserve.net - http://xf.home.ml.org

>... The word 'meaningful' when used today is nearly always meaningless.

Osmo

Other Threads