Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with: read( unit=file, fmt=*, iostat=Read_Code) ( alphas(i), i = 1, 5 )

146 views
Skip to first unread message

elzbieta...@gmail.com

unread,
Dec 27, 2012, 2:45:19 AM12/27/12
to
I have large program with:

real(kind=8), allocatable, save :: alphas(:)

if ( FirstPass ) then

allocate( alphas( data%aero_nalpha ) )
allocate( machs( data%aero_nmach ) )

!Read Alpha Data:
open( newunit=AlphaInput, file=data%AlphaInputFileName, action='read', form='formatted', &
access='stream', iostat=open_stat, status='old' )

if ( open_stat /= 0 ) then
write(unit=*, fmt="('In get_aero_forces can not open alpha input file!')")
stop
end if

read( unit=AlphaInput, fmt=*, iostat=stat ) ( alphas(i), i = 1, data%aero_nalpha )

close( unit=AlphaInput )

...more code...

end if

If file=data%AlphaInputFileName does not end with <new-line><EOF>, it fails to read last data item. I get: alphas(5) = junk instead of alphas(5) = 8.

I tried to duplicate this with small program:

program test_lc

use, intrinsic :: iso_fortran_env

integer :: Read_Code, file
integer, allocatable :: alphas(:)

allocate( alphas( 5 ) )

open ( newunit=file, file="alphas_input.dat", status="old", access='stream', form='formatted', action='read' )
read( unit=file, fmt=*, iostat=Read_Code) ( alphas(i), i = 1, 5 )
write ( *, * ) 'alphas: ', alphas

end program test_lc

Using same data file with for small program, small program works - it reads all data items, including last, even when I have 8<EOF>.

Large program uses: real(kind=8), allocatable, save :: alphas(:)
Small program uses: integer, allocatable :: alphas(:)

Why would this make difference using "list-directed I/O"?

If I change small program to: real(kind=8), allocatable, save :: alphas(:), it fails with last item like large program.

I also tried to use: access='sequential' but it still fails with 8<EOF>.

Data file:

-8
-4
0
4
8<EOF>


<Ella>


Elzbieta Burnett

unread,
Dec 27, 2012, 2:55:15 AM12/27/12
to
Data files are given to use without <new-line><EOF>. I don't want to
have to edit files.

<Ella>

Elzbieta Burnett

unread,
Dec 27, 2012, 3:15:15 AM12/27/12
to
On Dec 27, 2:55 am, Elzbieta Burnett <elzbieta.burn...@gmail.com>
wrote:
I use GNU Fortran (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)

Arjen Markus

unread,
Dec 27, 2012, 4:14:58 AM12/27/12
to
On Thursday, December 27, 2012 9:15:15 AM UTC+1, Elzbieta Burnett wrote:

> I use GNU Fortran (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)

I suspect this is a slight problem with gfortran itself. I tried your program
(using "real(kind(1.0d0))") with gfortran and Intel Fortran on Windows XP and
got the problem you reported with gfortran (error code -1) but not with Intel
Fortran.

If I add a period (.) to the last line, the program happily reads the file
without a single complaint.

I suggest you report it to the gfortran people - isntructions at http://gcc.gnu.org/fortran/

Regards,

Arjen

Richard Maine

unread,
Dec 27, 2012, 12:00:41 PM12/27/12
to
Arjen Markus <arjen.m...@gmail.com> wrote:

> On Thursday, December 27, 2012 9:15:15 AM UTC+1, Elzbieta Burnett wrote:
>
> > I use GNU Fortran (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
>
> I suspect this is a slight problem with gfortran itself.

That was my inclination as well, though I read the OP's post right
before heading to bed too late anyway and I didn't feel up to either
doing tests or carefully checking for a loophole in the standard.

For the access='sequential' case, all bets are off; a sequential file is
composed of records - not partial records. The standard gives no
guarantees on what behavior to expect for that case. I'd think that more
likely to cause a problem of that sort than to solve it.

But it seems to me that the access='stream' case ought to have worked.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Elzbieta Burnett

unread,
Dec 28, 2012, 3:34:27 AM12/28/12
to
On Dec 27, 12:00 pm, nos...@see.signature (Richard Maine) wrote:
I tried (notice: access='sequential'):

program test_lc

use, intrinsic :: iso_fortran_env

integer :: LineCount, Read_Code, file
!integer, allocatable :: alphas(:)
real(kind=8), allocatable :: alphas(:)
character (len=100) :: line

allocate( alphas( 5 ) )

open ( newunit=file, file='alphas_input.dat', status="old",
access='sequential', form='formatted', action='read' )

LineCount = 0

ReadLoop: do

read ( file, '(a)', iostat=Read_Code) line

if ( Read_Code /= 0 ) then
if ( Read_Code == iostat_end ) then
exit ReadLoop ! end of file --> line count found
else
write ( *, '( / "read error: ", I0 )' ) Read_Code
stop
end if
end if

LineCount = LineCount + 1

read ( unit=line, fmt=* ) alphas( LineCount )
write ( *, * ) alphas( LineCount )

end do ReadLoop

end program test_lc

With alphas_input.dat:

-8
-4
0
4
8<EOF>

I got:

-8.0000000000000000
-4.0000000000000000
0.0000000000000000
4.0000000000000000
8.0000000000000000

Then <new-line> before <EOF> in data file is not required when file is
sequential. It read final item, 8, as complete record. Correct?

<Ella>

Elzbieta Burnett

unread,
Dec 28, 2012, 4:09:27 AM12/28/12
to
On Dec 28, 3:34 am, Elzbieta Burnett <elzbieta.burn...@gmail.com>
wrote:
If I change to (notice: access='stream'):

open ( newunit=file, file='alphas_input.dat', status='old',
access='stream', form='formatted', action='read' )

I get:

-8.0000000000000000
-4.0000000000000000
0.0000000000000000
4.0000000000000000

Again with alphas_input.dat:

-8
-4
0
4
8<EOF>

Last data item is missing. You said this case where: access='stream',
is not defined. Correct?

Whenever I use:

read ( file, '(a)', iostat=Read_Code) line

I should always use: access='stream. Correct?

<Ella>

glen herrmannsfeldt

unread,
Dec 28, 2012, 6:50:43 AM12/28/12
to
Elzbieta Burnett <elzbieta...@gmail.com> wrote:
> On Dec 28, 3:34 am, Elzbieta Burnett <elzbieta.burn...@gmail.com>
> wrote:
>> On Dec 27, 12:00 pm, nos...@see.signature (Richard Maine) wrote:

(snip)
>> I tried (notice: access='sequential'):

(snip)

>>   open ( newunit=file, file='alphas_input.dat', status="old",
>> access='sequential', form='formatted', action='read' )

>>   LineCount = 0
>>   ReadLoop: do
>>      read ( file, '(a)', iostat=Read_Code) line

(snip)

>> -8
>> -4
>> 0
>> 4
>> 8<EOF>

Which OS are you using?

Do you have a program like unix od to dump the contents of a file
byte by byte, including line terminating characters?

>> I got:

>>  -8.0000000000000000
>>  -4.0000000000000000
>>   0.0000000000000000
>>   4.0000000000000000
>>   8.0000000000000000

It is certainly possible that it will work, but in many cases it
makes your file (or program if it is the program source file)
system dependent.

It sometimes happens accidentally, but then so do many other
things. Sometimes lines get deleted from the middle of a file,
or someone accidentally does a global find/replace and replaces
too much.

>> Then <new-line> before <EOF> in data file is not required when
>> file is sequential.  It read final item, 8, as complete record.
>> Correct?

On systems that use line terminating characters (at least unix,
MS-DOS and Windows) the results are system dependent.

> If I change to (notice: access='stream'):

> open ( newunit=file, file='alphas_input.dat', status='old',
> access='stream', form='formatted', action='read' )

> I get:

> -8.0000000000000000
> -4.0000000000000000
> 0.0000000000000000
> 4.0000000000000000

> Again with alphas_input.dat:

> -8
> -4
> 0
> 4
> 8<EOF>

Your results are surprising, but certainly possible.

You don't say what the IOSTAT value is, or else I already
snipped it out. The usual question is when EOF is detected.
Systems might detect other problems and report them other
than EOF.

The tradition of formatted sequential I/O is that it is record
(line) oriented. That goes back to the beginning of Fortran, years
before anyone even thought about a standard, and usually on
systems that didn't use record terminating characters.
(Fixed length records were popular for a long time, especially
ones with 80 character long records.)

> Last data item is missing. You said this case where:
> access='stream', is not defined. Correct?

Access='stream' is more recent, and mostly designed to
work in a similar way to the C library I/O routines.

> Whenever I use:

> read ( file, '(a)', iostat=Read_Code) line

> I should always use: access='stream. Correct?

Pretty much, you should use access='stream' if you want things
to work like C.

-- glen

Richard Maine

unread,
Dec 28, 2012, 12:19:49 PM12/28/12
to
Elzbieta Burnett <elzbieta...@gmail.com> wrote:

> On Dec 28, 3:34 am, Elzbieta Burnett <elzbieta.burn...@gmail.com>
> wrote:
> > On Dec 27, 12:00 pm, nos...@see.signature (Richard Maine) wrote:

> > > For the access='sequential' case, all bets are off; a sequential file is
> > > composed of records - not partial records. The standard gives no
> > > guarantees on what behavior to expect for that case. I'd think that more
> > > likely to cause a problem of that sort than to solve it.
> >
> > > But it seems to me that the access='stream' case ought to have worked.
...
> > Then <new-line> before <EOF> in data file is not required when file is
> > sequential. It read final item, 8, as complete record. Correct?

No.

> Last data item is missing. You said this case where: access='stream',
> is not defined. Correct?

No. That's exactly the opposite of what I said. See above. I said that
the access='stream' case ought to have worked, but that it is the
sequential case that is not defined by the standard.
>
> Whenever I use:
>
> read ( file, '(a)', iostat=Read_Code) line
>
> I should always use: access='stream. Correct?

No. For a start, I can't agree with the "always" there. That's way to
broad for that statement. In fact, I would say that stream versus
sequential has nothing in particular to do with anything in that
particular statement.

What I would say is that stream seems a better bet when you have
incomplete records as in your data file. This has nothing to do with the
choice of format or anything else about the syntax of the read
statement.

Richard Maine

unread,
Dec 28, 2012, 12:22:22 PM12/28/12
to
Richard Maine <nos...@see.signature> wrote:

> ...That's way to
> broad for that statement....

Ouch. Yes, I do know better.

s/to/too/.

Elzbieta Burnett

unread,
Dec 28, 2012, 1:40:20 PM12/28/12
to
Sorry. Actually, I meant:

Whenever I use:

read ( file, '(a)', iostat=Read_Code) line

I should always use: access='sequential'. Correct?

(I cut and paste wrong piece of code. Should have caught this.)

With this code, access='sequential' works better. It reads last data
item. Isn't

read ( file, '(a)', iostat=Read_Code) line

inherently reading of record where access='sequential' would be more
appropriate?

<Ella>

Richard Maine

unread,
Dec 28, 2012, 2:01:35 PM12/28/12
to
Elzbieta Burnett <elzbieta...@gmail.com> wrote:

> Sorry. Actually, I meant:
>
> Whenever I use:
>
> read ( file, '(a)', iostat=Read_Code) line
>
> I should always use: access='sequential'. Correct?
>
> (I cut and paste wrong piece of code. Should have caught this.)
>
> With this code, access='sequential' works better. It reads last data
> item. Isn't
>
> read ( file, '(a)', iostat=Read_Code) line
>
> inherently reading of record where access='sequential' would be more
> appropriate?

Still no. Formattted stream access also has records. It thus can be
perfectly fine for reading records.

Formatted stream can *ALSO* deal with partial records, but it is simply
wrong to imply that it can't deal with records. In fact, most of the
time formatted stream will be reading from records. Having a partial
record at the end of a file is just a special case. Even when you have
that special case, all the other records in the file are normal records.
How would you expect to read them? No, you don't do it by switching
between sequental and stream access in the middle of reading the file;
that isn't allowed.

I think something fundamental is being misunderstood here, but I'm not
sure what it is, which makes it hard for me to address it.

Perhaps you are being led astray by what has been mentioned as
apparently being a problem with some version(s) of gFortran. No, it is
not valid to generalize from such a problem.

Elzbieta Burnett

unread,
Dec 28, 2012, 3:36:29 PM12/28/12
to
On Dec 28, 2:01 pm, nos...@see.signature (Richard Maine) wrote:
Then fact that my code works with access='sequential' and not
access='stream' is a gfortran issue?

<Ella>

Richard Maine

unread,
Dec 28, 2012, 4:29:16 PM12/28/12
to
Elzbieta Burnett <elzbieta...@gmail.com> wrote:

> Then fact that my code works with access='sequential' and not
> access='stream' is a gfortran issue?

Yes. That's what it appears to me. I haven't sat down to verify it.
You've provided enough data for me to do so, but I just haven't taken
the time (and am about to run out on some errands, so I'll not be doing
it right now either). But based on your reports, that's what I'd say it
sounds like. It not working with stream probably ought to be reported to
the gFortran folk as a bug.

Tobias Burnus

unread,
Dec 28, 2012, 6:05:51 PM12/28/12
to
Richard Maine wrote:
> Elzbieta Burnett <elzbieta...@gmail.com> wrote:
>> Then fact that my code works with access='sequential' and not
>> access='stream' is a gfortran issue?
>
> Yes. That's what it appears to me. I haven't sat down to verify it.
> You've provided enough data for me to do so, but I just haven't taken
> the time (and am about to run out on some errands, so I'll not be doing
> it right now either). But based on your reports, that's what I'd say it
> sounds like. It not working with stream probably ought to be reported to
> the gFortran folk as a bug.

I have opened yesterday a bug report for that, but Elzbieta also wrote
this morning to the gfortran mailing list. A patch has already been
posted for the the issue, which affects reading real, complex and
character data. (integer and logical were fine; I think reading a real
which contained a "." worked without trailing new line.)

I have to admit that I have not quite followed the discussion about the
difference between sequential and stream within this thread - but I
think with the patch either should work.

Tobias

Richard Maine

unread,
Dec 28, 2012, 6:32:59 PM12/28/12
to
Tobias Burnus <bur...@net-b.de> wrote:

> I have to admit that I have not quite followed the discussion about the
> difference between sequential and stream within this thread - but I
> think with the patch either should work.

Both working would be fine - preferable even. My point was that with
stream, it ought to work per my understanding of the standard, but that
with sequential, the standard was mute so that the user could not count
on any specific behavior. Still, it is probably "nicest" for it to work
with sequential as well.

glen herrmannsfeldt

unread,
Dec 28, 2012, 7:15:45 PM12/28/12
to
Richard Maine <nos...@see.signature> wrote:
> Tobias Burnus <bur...@net-b.de> wrote:

>> I have to admit that I have not quite followed the discussion about the
>> difference between sequential and stream within this thread - but I
>> think with the patch either should work.

It is an interesting question. For sequential the standard describes
records, and there is some question about an unterminated file end.
That is, the last line may or may not be a record.

> Both working would be fine - preferable even. My point was that with
> stream, it ought to work per my understanding of the standard, but that
> with sequential, the standard was mute so that the user could not count
> on any specific behavior. Still, it is probably "nicest" for it to work
> with sequential as well.

I suppose I agree with "ought." As far as I know the standard doesn't
require it to work in either case. Well, as with C, it depends on how you
actually read the file. A program using stream could specifically look
for the line terminator, and fail (in various ways) if it isn't there.

As far as I know, IOSTAT still works, and can still have the IOSTAT_EOR
value even with STREAM I/O. I suppose it could also be IOSTAT_EOF
reading to the end of a line with no line terminator, or maybe a
different, non-zero value.

-- glen

e p chandler

unread,
Dec 28, 2012, 6:24:40 PM12/28/12
to
"Elzbieta Burnett" wrote

> With this code, access='sequential' works better. It reads last data
> item. Isn't

> read ( file, '(a)', iostat=Read_Code) line

> inherently reading of record where access='sequential' would be more
> appropriate?

access='sequential' is the default value, if nothing is specified. This is
the usual way that Fortran reads and writes files. The opposite of
'sequential' is not 'stream', but 'direct'. 'direct' means random-access
instead of sequential-access. 'stream' may work better in special cases.

The usual reason to use stream I/O is not something sepcified by Fortran's
language standards. Stream reads and writes raw data. It does more or less
what some forms of "C" I/O do. Suppose you want to transfer a variable from
memory directly to a file, say a REAL variable. Formatted output converts it
to text and writes that to the file. Unformatted output writes directly to
the file but in practice there may be additional data written to the file as
well. Usually this includes a file header and record headers and trailers.
One way to avoid this extra data is to use unformatted-stream.

Fortran does not specify at all how records or files are delimited, or even
that they are delimited at all. It does not specify file headers, record
headers or record trailers. Those are a function of the compiler, run-time
library and operating system. All Fortran guarantees is that a Fortran
program can read what it just wrote.

----- e


Richard Maine

unread,
Dec 28, 2012, 9:19:22 PM12/28/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
[from elsethread]

> It is an interesting question. For sequential the standard describes
> records, and there is some question about an unterminated file end.
> That is, the last line may or may not be a record.

I disagree that there is a question about tis in the standard. The
standard describes a sequential file as being composed of records. It
has no concept of a "line that is not a record" or anything else of the
sort. I don't see any "question" at all about this in the standard for
sequential files. If it isn't a record, then it isn't part of a
sequential file as defined by the standard.

Now the definition of what constitutes a record is not specified by the
standard. A compiler is free to consider there to be a final record even
without physical record terminator mark. That kind of decision is
compiler-dependent. Also, a compiler might choose to allow processing a
partial record as an extension. So in those senses, there is question as
to whether the file might or might not work. But those are questions
about the compiler's definition of records and about possible
extensions. I see nothing at all in the standard about partial records
in sequential files, so I don't know what question this is that you
might be referring to.

> Richard Maine <nos...@see.signature> wrote:

> > Both working would be fine - preferable even. My point was that with
> > stream, it ought to work per my understanding of the standard, but that
> > with sequential, the standard was mute so that the user could not count
> > on any specific behavior. Still, it is probably "nicest" for it to work
> > with sequential as well.
>
> I suppose I agree with "ought." As far as I know the standard doesn't
> require it to work in either case. Well, as with C, it depends on how you
> actually read the file. A program using stream could specifically look
> for the line terminator, and fail (in various ways) if it isn't there.
>
> As far as I know, IOSTAT still works, and can still have the IOSTAT_EOR
> value even with STREAM I/O. I suppose it could also be IOSTAT_EOF
> reading to the end of a line with no line terminator, or maybe a
> different, non-zero value.

You appear to be misreading the intention of my "ought". I meant it in
the sense of being required by the standard and thus ought to work
because compilers ought to adhere to the standard.

Stream I/O allows for partial records. That's not just something that
might be nice or might happen to be ok depending on the implementation.
It is explicitly specified in the Fortran standard. From f2003, 9.2.2.3,
the second (1) in the section.

"Some file storage units of the file may contain record markers; this
imposes a record structure on the file in addition to the stream
structure. There might or might not be a record marker at the end of
the file. If there is no record marker at the end of the file, the
final record is incomplete."

Yes, IOSTAT_EOR is allowed for stream, but that is irrelevant here
because IOSTAT_EOR is allowed only for non-advancing I/O. Lots of people
seem to get that one wrong. Non-advancing I/O is allowed for both stream
and sequential, but it is not being used in the case under discussion.

IOSTAT_EOF is indeed what you get for reading past the end of a stream
file, and that has nothing to do with whether there is a final record
marker or not. One doesn't really have to guess about these things.
There are things in the standard that are subtle and tricky to read, but
this isn't among them.

F2003, 9.10:

"An end-of-file considtion occurs in the following cases:
...
(3) When an attempt is made to read beyond the end of a stream file."

But I don't see that the code shown involes an attempt to read beyond
the end of the stream file. It reads to the end, but not beyond it.

The only minor caveat I can see is that the wording for list-directed
input doesn't look like it was redone to reflect partial records. I can
see that one might quibble about details relating to that. But that
doesn't sound to me like what you are looking at.

glen herrmannsfeldt

unread,
Dec 28, 2012, 9:39:57 PM12/28/12
to
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> [from elsethread]

>> It is an interesting question. For sequential the standard describes
>> records, and there is some question about an unterminated file end.
>> That is, the last line may or may not be a record.

> I disagree that there is a question about tis in the standard. The
> standard describes a sequential file as being composed of records. It
> has no concept of a "line that is not a record" or anything else of the
> sort. I don't see any "question" at all about this in the standard for
> sequential files. If it isn't a record, then it isn't part of a
> sequential file as defined by the standard.

> Now the definition of what constitutes a record is not specified by the
> standard. A compiler is free to consider there to be a final record even
> without physical record terminator mark. That kind of decision is
> compiler-dependent. Also, a compiler might choose to allow processing a
> partial record as an extension. So in those senses, there is question as
> to whether the file might or might not work. But those are questions
> about the compiler's definition of records and about possible
> extensions. I see nothing at all in the standard about partial records
> in sequential files, so I don't know what question this is that you
> might be referring to.

Yes, exactly that. If a record is supposed to have a terminator
and doesn't, then it isn't a complete record (according to that
systems' definition) and so I call it a partial record.


(snip, I wrote)
What does list directed input do when it gets to where the last
line terminator should be for stream? It doesn't know that it is
at the end of the list item until it reads something past that item.

If it hits EOF while trying to finish the list item, is it reported
as EOF?

> F2003, 9.10:

> "An end-of-file considtion occurs in the following cases:
> ...
> (3) When an attempt is made to read beyond the end of a stream file."

> But I don't see that the code shown involes an attempt to read beyond
> the end of the stream file. It reads to the end, but not beyond it.

> The only minor caveat I can see is that the wording for list-directed
> input doesn't look like it was redone to reflect partial records. I can
> see that one might quibble about details relating to that. But that
> doesn't sound to me like what you are looking at.

I think it is. With format descriptors, you can specify the exact number
of characters needed, and expect it not to need more. Not so easy with
list directed.

For C scanf(), you read list items independent of record boundaries
(if any).

But some C programs read lines, such as with fgets() and then parse
the line, maybe with sscanf(). Depending on how it process the
fgets() buffer, it can fail to detect the last line.

Even though C I/O is logically character at a time, it is still
described based on records. I believe the standard in text mode
allows it to fail to work on an unterminated line. In binary
mode, you should get every character.

-- glen

Richard Maine

unread,
Dec 28, 2012, 9:45:04 PM12/28/12
to
e p chandler <ep...@juno.com> wrote:

> The opposite of
> 'sequential' is not 'stream', but 'direct'.

No. There is no "opposite" of stream at all. It is not something that
has an opposite. That's about like saying that the opposite of "cat" is
"dog". There are 3 access methods defined by the standard these days:
"sequential", "direct", and "stream". Other access methods are
concievable as extensions. Things like "keyed" or "isam" come to mind.
None of these are opposites in much of a meaningful sense. There is a
reason that access takes character values instead of logical ones.

> The usual reason to use stream I/O is not something sepcified by Fortran's
> language standards.

I'd there are quite a few reasons for using stream. You can probably
find people who would argue for using stream for almost everything.

> ...All Fortran guarantees is that a Fortran
> program can read what it just wrote.

This seems like an overgeneralization. I'd say it was accurate for
unformatted sequential. But stream is also part of the Fortran standard
these days. I more than half get the impression that you are considering
"Fortran" to not include stream.

Interoperability was the prime motivation for introducing stream,
although other issues did also get mixed in. While I'll admit that
"guarantee" might be too strong a word, an explicit intent of at least
unformatted stream is to allow Fortran to read and write things not
defined within Fortran.

Also, while again "guarantee" is too strong a word, there is a strong
expectation that Fortran formatted sequential files are "text" files as
defined by the operating system conventions. One could certainly claim
standard conformance for a compiler whose text files could not be
printed, edited, or otherwise used for anything other than input to
another Fortran program, but I doubt you'd find such a compiler to be
commercially viable. (There have been special cases of Fortran compilers
that didn't support I/O at all, but those were very special cases.)

The case that started this thread involves some uncertainty about
precisely what constitutes a valid "text" file for the operating systems
in question. It gets messier because Fortran's traditional
record-oriented concepts don't quite mesh with definitions of "text"
files that accomodate partial records.

Richard Maine

unread,
Dec 28, 2012, 10:09:06 PM12/28/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> What does list directed input do when it gets to where the last
> line terminator should be for stream? It doesn't know that it is
> at the end of the list item until it reads something past that item.
>
> If it hits EOF while trying to finish the list item, is it reported
> as EOF?

> Richard Maine <nos...@see.signature> wrote:

> > F2003, 9.10:
>
> > "An end-of-file considtion occurs in the following cases:
> > ...
> > (3) When an attempt is made to read beyond the end of a stream file."
>
> > But I don't see that the code shown involes an attempt to read beyond
> > the end of the stream file. It reads to the end, but not beyond it.
>
> > The only minor caveat I can see is that the wording for list-directed
> > input doesn't look like it was redone to reflect partial records. I can
> > see that one might quibble about details relating to that. But that
> > doesn't sound to me like what you are looking at.
>
> I think it is. With format descriptors, you can specify the exact number
> of characters needed, and expect it not to need more. Not so easy with
> list directed.

I disagree with your interpretation there. Seems to me that there is a
well-defined data field. The read statement reads only the data in that
field. That the underlying implementation might or might not involve
reading ahead to figure out that it is at the end of the file seems
irrelevant. There are certainly implementation methods that do not
involve trying to read the next character. Having separate file size
information seems like an obvious one. But in any case, the standard
isn't talking about implementation internals. It is talking about the
user code. The user code doesn't try to read past the end of the file;
it reads to the end, but not past it.

I think you are focussing too much on how the implementation might work,
and even on only one possible way that an implementation might work. But
that's not how the standard describes things. This being a question
about the standard, implementation details are not really the place to
look unless one is trying to claim that the standard is defective
because it describes something that is impractical to implement.

I'll buy that there is at least some wiggle room for alternate
interpretations here. That's what I was referring to when I said that it
looked like the wording wasn't redone to reflect partial records. The
existing wording isn't explicit about defining the data field in this
case. Might be worth an interpretation. I think I can guess what the
answer to the interpretation would be, but I'll admit it isn't open and
shut.

The C stuff is irrelevant. This is a question about the Fortran
standard.

jski

unread,
Dec 30, 2012, 4:24:51 AM12/30/12
to
So the upshot of all these ruminations on Elzbieta's question is that
there is no definition of record (in the standard) but for practical
purposes if your code reaches an EOF when reading a "line" that should
be interpreted as an end-of-record.

BTW, this problem also exists in BASH scripts (for whatever it's
worth):

FILENAME=$1
while read line
do
echo $line
done < $FILENAME


---John

Ron Shepard

unread,
Dec 30, 2012, 2:56:35 PM12/30/12
to
In article
<98e22c57-5bfc-4659...@r14g2000vbe.googlegroups.com>,
jski <john.chl...@gmail.com> wrote:

> So the upshot of all these ruminations on Elzbieta's question is that
> there is no definition of record (in the standard) but for practical
> purposes if your code reaches an EOF when reading a "line" that should
> be interpreted as an end-of-record.
>
> BTW, this problem also exists in BASH scripts (for whatever it's
> worth):
>
> FILENAME=$1
> while read line
> do
> echo $line
> done < $FILENAME

There are many of the standard unix utilities that have this same
problem with partial records. I have not checked lately about this,
but this has been the situation since the 80's when I first started
using unix based OSs.

That is why I don't think it is particularly productive to expect a
fortran compiler/runtime to handle this situation. In unix, you are
constantly using all kinds of tools and utilities to analyze and
edit text files. It doesn't really make sense to expend effort to
get one of them (which happens to be written in fortran) to work
correctly when almost certainly the others will fail somewhere.

The problem here is the program that created these text files in the
first place. Fix that one problem, and everything else, whether
written in fortran or perl or awk or bash or whatever, will work
correctly.

$.02 -Ron Shepard

jski

unread,
Dec 31, 2012, 4:53:54 AM12/31/12
to
On Dec 30, 2:56 pm, Ron Shepard <ron-shep...@NOSPAM.comcast.net>
wrote:
> In article
> <98e22c57-5bfc-4659-b990-d0704cdf5...@r14g2000vbe.googlegroups.com>,
How would you feel if a text file with Fortran code in it ended "end
program<EOF>" and you got a compiler error because the final line
wasn't parsed?

---John

Dan Nagle

unread,
Dec 31, 2012, 8:01:44 AM12/31/12
to
Hi,

On 2012-12-31 09:53:54 +0000, jski said:
>
> How would you feel if a text file with Fortran code in it ended "end
> program<EOF>" and you got a compiler error because the final line
> wasn't parsed?

That's actually trickier than you might think.

En end-statement is forbidden to be continued
to the next line, and the compiler could claim
it was confused about whether there was a next line
since there was no end of record marker.
(Not a strong claim, but a rational claim.)

--
Cheers!

Dan Nagle

Clive Page

unread,
Dec 31, 2012, 9:31:14 AM12/31/12
to
Yes, once upon a time it could be tricky. In order to avoid such
problems I always used to put an extra blank line after the END
statement, but I once encountered a compiler which issued an error
message for it, as it took it as the first statement of the next program
unit, and a completely blank program unit was not permitted.
Fortunately those who sold compilers like that are no longer in business.

--
Clive Page

Gordon Sande

unread,
Dec 31, 2012, 9:56:38 AM12/31/12
to
It used to happen! Not sure that vendor is still with us or maybe they changed
to a better quality of implementation.

If one has a very indulgent text editor and is hopping between systems with
differing line end conventions one can see a variation on this theme where
some lines get ignored.

The worst are the Unix utilities that are very unforgiving. A Mac file (CR end
of line) produces absolutely nothing from BASH (LF end of line) which is rather
easy to do if one is switching from standard Mac stuff to terminal which is
really Unix.

Of late I see that many text editors (also known as programmers editors) have
an option to standardize and fix all line ends to avoid the issues of Mac vrs
Windows vrs Unix. Most will produce whichever of the three variants you want
from any of the systems. Little untilites which will do the fixups/conversions
are very easy to find and easy to use.

Programs that do not follow the conventions of the system they are on
are broken.
The cure is to fix that program and not to insist that every other program need
fixing. Sort of like the issues with mentally ill folks who think they are fine
and insist that the rest of the world is insane.



e p chandler

unread,
Dec 31, 2012, 10:44:36 AM12/31/12
to
On Thursday, December 27, 2012 2:45:19 AM UTC-5, elzbieta...@gmail.com wrote:
> I have large program with:
>
>
>
> real(kind=8), allocatable, save :: alphas(:)
>
>
>
> if ( FirstPass ) then
>
>
>
> allocate( alphas( data%aero_nalpha ) )
>
> allocate( machs( data%aero_nmach ) )
>
>
>
> !Read Alpha Data:
>
> open( newunit=AlphaInput, file=data%AlphaInputFileName, action='read', form='formatted', &
>
> access='stream', iostat=open_stat, status='old' )
>
>
>
> if ( open_stat /= 0 ) then
>
> write(unit=*, fmt="('In get_aero_forces can not open alpha input file!')")
>
> stop
>
> end if
>
>
>
> read( unit=AlphaInput, fmt=*, iostat=stat ) ( alphas(i), i = 1, data%aero_nalpha )
>
>
>
> close( unit=AlphaInput )
>
>
>
> ...more code...
>
>
>
> end if
>
>
>
> If file=data%AlphaInputFileName does not end with <new-line><EOF>, it fails to read last data item. I get: alphas(5) = junk instead of alphas(5) = 8.
>
>
>
> I tried to duplicate this with small program:
>
>
>
> program test_lc
>
>
>
> use, intrinsic :: iso_fortran_env
>
>
>
> integer :: Read_Code, file
>
> integer, allocatable :: alphas(:)
>
>
>
> allocate( alphas( 5 ) )
>
>
>
> open ( newunit=file, file="alphas_input.dat", status="old", access='stream', form='formatted', action='read' )
>
> read( unit=file, fmt=*, iostat=Read_Code) ( alphas(i), i = 1, 5 )
>
> write ( *, * ) 'alphas: ', alphas
>
>
>
> end program test_lc
>
>
>
> Using same data file with for small program, small program works - it reads all data items, including last, even when I have 8<EOF>.
>
>
>
> Large program uses: real(kind=8), allocatable, save :: alphas(:)
>
> Small program uses: integer, allocatable :: alphas(:)
>
>
>
> Why would this make difference using "list-directed I/O"?
>
>
>
> If I change small program to: real(kind=8), allocatable, save :: alphas(:), it fails with last item like large program.
>
>
>
> I also tried to use: access='sequential' but it still fails with 8<EOF>.
>
>
>
> Data file:
>
>
>
> -8
>
> -4
>
> 0
>
> 4
>
> 8<EOF>
>
>
>
>
>
> <Ella>

Richard Maine

unread,
Dec 31, 2012, 11:33:49 AM12/31/12
to
jski <john.chl...@gmail.com> wrote:

> How would you feel if a text file with Fortran code in it ended "end
> program<EOF>" and you got a compiler error because the final line
> wasn't parsed?

That one is easy to answer because it doesn't require speculation. I've
used compilers that did exactly that. How I felt was that the source
file needed fixing.

It didn't tend to come up with code that I wrote myself because I turned
on the option in my favorite text editor of the time to always force a
line terminator at the end of the file when saving.

Tobias Burnus

unread,
Dec 31, 2012, 2:34:14 PM12/31/12
to
Gordon Sande wrote:
> The worst are the Unix utilities that are very unforgiving. A Mac file
> (CR end
> of line) produces absolutely nothing from BASH (LF end of line) which is
> rather
> easy to do if one is switching from standard Mac stuff to terminal which is
> really Unix.
>
> Of late I see that many text editors (also known as programmers editors)
> have
> an option to standardize and fix all line ends to avoid the issues of
> Mac vrs
> Windows vrs Unix.

Fortunately, finding the Mac ending (CR) is very rare nowadays since
Apple as switch to a unixoid operating system. (MacOS X/Darwin is based
on BSD - I think it is based on FreeBSD.)

I think most currently employed compilers handle both LF and CR-LF but
not CR. I recall that I once encountered a CR file (about 6 years ago),
which had then be "convert"ed into (CR-)LF before it could be compiled
(under Linux).

Actually, what's case for compilers reading source files is also the
case for sequential formatted I/O, where most compilers handle both LF
and CR-LF as record marker. I am sure you can confuse them if you use a
CR-only file. And I believe that there compilers which only like CR-LF
or LF and no files which don't end in either.

Tobias

Ron Shepard

unread,
Dec 31, 2012, 3:14:34 PM12/31/12
to
In article
<8d07b993-f793-4492...@v7g2000yqv.googlegroups.com>,
I'm not sure what you are asking?

The above situation happens all the time, so it is not hypothetical.
The answer is that I would fix the source code. This is almost
certainly caused when I entered that line in a text editor by not
included the final line terminator (CR, or LF, or whatever). I
would consider that my mistake, not the compiler's. This almost
certainly would not happen if the source code were generated by a
perl script or one of the other unix utilities, they would create a
complete line in the file.

$.02 -Ron Shepard

Dan Nagle

unread,
Dec 31, 2012, 4:39:05 PM12/31/12
to
Hi,

On 2012-12-31 14:31:14 +0000, Clive Page said:

>
> Yes, once upon a time it could be tricky. In order to avoid such
> problems I always used to put an extra blank line after the END
> statement, but I once encountered a compiler which issued an error
> message for it, as it took it as the first statement of the next
> program unit, and a completely blank program unit was not permitted.
> Fortunately those who sold compilers like that are no longer in
> business.

That behavior was specifically outlawed, for the nuiscance value
you describe. See 3.3.2.3

--
Cheers!

Dan Nagle

Thomas Koenig

unread,
Dec 31, 2012, 5:39:52 PM12/31/12
to
Ron Shepard <ron-s...@NOSPAM.comcast.net> schrieb:

> This is almost
> certainly caused when I entered that line in a text editor by not
> included the final line terminator (CR, or LF, or whatever). I
> would consider that my mistake, not the compiler's. This almost
> certainly would not happen if the source code were generated by a
> perl script or one of the other unix utilities, they would create a
> complete line in the file.

Actually, in a perl script, it is rather trivial to forget the "\n"
at the end of an output statement (like in a C program).

Gordon Sande

unread,
Dec 31, 2012, 9:11:00 PM12/31/12
to
On 2012-12-31 15:34:14 -0400, Tobias Burnus said:

> Gordon Sande wrote:
>> The worst are the Unix utilities that are very unforgiving. A Mac file
>> (CR end
>> of line) produces absolutely nothing from BASH (LF end of line) which is
>> rather
>> easy to do if one is switching from standard Mac stuff to terminal which is
>> really Unix.
>>
>> Of late I see that many text editors (also known as programmers editors)
>> have
>> an option to standardize and fix all line ends to avoid the issues of
>> Mac vrs
>> Windows vrs Unix.
>
> Fortunately, finding the Mac ending (CR) is very rare nowadays since
> Apple as switch to a unixoid operating system. (MacOS X/Darwin is based
> on BSD - I think it is based on FreeBSD.)

As someone who has used Macs from before MacOsX I find them all the
time. Most of the text
editors I find useful have the habit of not changing the conventions
that already exist
in a file even if they are capable of producing all the variants. The
text editor that I
wish I could still use was never translated to go from MaxOs to MacOsX,
But one has to learn
to tolerate even the improvements for worse as well as the many
improvements for better
that MacOsx represents.

john.chl...@gmail.com

unread,
Jan 1, 2013, 12:34:04 AM1/1/13
to
On Monday, December 31, 2012 11:33:49 AM UTC-5, Richard Maine wrote:
I had to add the follow lines to ~/.emacs:

(setq mode-require-final-newline nil)
(setq require-final-newline 'ask)

to prevent Emacs from automatically adding a newline at the end of file just to test these cases. Emacs, by default, adds a newline at the end of the file if one is not present.

---John

Richard Maine

unread,
Jan 1, 2013, 10:54:53 AM1/1/13
to
<john.chl...@gmail.com> wrote:

> On Monday, December 31, 2012 11:33:49 AM UTC-5, Richard Maine wrote:

> > It didn't tend to come up with code that I wrote myself because I turned
> > on the option in my favorite text editor of the time to always force a
> > line terminator at the end of the file when saving.

> I had to add the follow lines to ~/.emacs:
>
> (setq mode-require-final-newline nil)
> (setq require-final-newline 'ask)
>
> to prevent Emacs from automatically adding a newline at the end of file
> just to test these cases. Emacs, by default, adds a newline at the end
> of the file if one is not present.

Looks familliar except that it wasn't the default in the version I used
to use, so I added something more like

(setq mode-require-final-newline t)

to a startup file. I think I might have done it in the system-wide
startup file instead of just my personal one, as I was the one
installing emacs.

William Clodius

unread,
Jan 1, 2013, 5:03:59 PM1/1/13
to
But for arbitrary programs there may be more than one source of input
files. In particular for text (ASCII) inputs, the source may be output
by another arbitrary user of a text editor. Getting an arbitrary user to
consistently add an EOL at the end of the last sigificant line of the
file can be impractical. (Historically there have also been text editors
and data transfer protocalls that have eliminated trailing empty lines
as not containing significant text, so having users add the end of line
was not always sufficient.) What should be sufficient is coding to deal
with the problem lines ending with EOF and not having a compiler runtime
get in the way of that coding.

Richard Maine

unread,
Jan 1, 2013, 6:37:44 PM1/1/13
to
William Clodius <wclo...@earthlink.net> wrote:

> What should be sufficient is coding to deal
> with the problem lines ending with EOF and not having a compiler runtime
> get in the way of that coding.

Many things "should be" so. But what actually is so is that you cannot
count on how such files will be handled, either by pre-f2003 Fortran or
by various other means. Trying to alter the past doesn't tend to work
very well.

As of f2003, stream I/O provides a standard way to deal with them. There
does seem to be some disagreement about the exact interpretation of
list-directed format input for the last field, as discussed earlier in
this thread, but that's a pretty minor detail.

Prior to f2003, you just can't count on being able to read the last line
of such files at all. The standard doesn't guarantee it, and there exist
compilers that won't do it. Whether that "should" have been the case is
a matter of spilt milk.
0 new messages