Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Problem with nonadvancing input

Ian_Thompson
Beginner
970 Views
When compiled with ifort Version 12.1.3.289 Build 20120130 on Mac OS X (Lion), the program below never reaches the second line of the file 'test.dat'. Instead, the end-of-record condition occurs repeatedly. Section 9.3.4.4 (clause 4) of the Fortran standard says

For nonadvancing input, if no error condition or end-of-file condition occurred, but an end-of-record condition (9.11) occurred, the file is positioned after the record just read.

Therefore I think this is a bug.

[fortran]program test use iso_fortran_env , only : iostat_end , iostat_eor implicit none integer :: ios character :: c open ( unit = 10 , file = "test.dat" , form = 'formatted' , access = 'stream' ) do read (10,fmt='( a1 )',advance='no',iostat=ios) c if ( ios == iostat_eor ) then write (*,*) write (*,*) "Line ends. Press return to continue." read (*,*) else if ( ios == iostat_end ) then write (*,*) write (*,*) "File ends" exit else write (*,fmt='( a1 )',advance='no') c end if end do end program[/fortran]
The file 'test.dat' contains the following

This is the first line
This is the second line
0 Kudos
8 Replies
mecej4
Honored Contributor III
970 Views
You are opening the data file as a stream file, but expecting EOR to be detected. By definition, stream files have a stream of bytes, none of which is interpreted to have any special significance. More simply put, stream files have no records.

Simply remove the access=stream modifier from the OPEN statement.
0 Kudos
IanH
Honored Contributor III
970 Views
Maybe for unformatted stream, but for formatted stream the newline character (as returned by the NEW_LINE intrinsic) delimits records.
0 Kudos
Ian_Thompson
Beginner
970 Views
As I said, EOR is detected. The standard is clear about what should happen next.
0 Kudos
Ian_Thompson
Beginner
970 Views
IanH = Ian Hounam?
0 Kudos
mecej4
Honored Contributor III
970 Views
Ian, are you sure that NEW_LINE pertains to input ?

The Fortran 2003 standard, Section 9 says:

18 A file composed of file storage units is called a stream file. A processor may allow a file to be viewed
19 both as a record file and as a stream file; in this case the relationship between the file storage units when
20 viewed as a stream file and the records when viewed as a record file is processor dependent.

and Section 13.7.85 says this about NEW_LINE (I added the emphasis):

2 Case (iii): Otherwise, the result is a processor-dependent character that represents a new
3 line in output to files connected for formatted stream output if there is such a
4 character.

Since Intel Fortran uses 4 bytes as the "file storage unit", and stream files may contain CR in addition to LF, the standard does not by itself settle the question.

Reading the Intel documentation did not lead me to a definite answer. I get the impression that mixing stream and record access on an input file is fraught with unpredictability.
0 Kudos
Steven_L_Intel1
Employee
970 Views
The Fortran 2008 standard (I did not look at 2003) is clear on what should happen.

In 9.3..3.4 (Stream access), it says:

"When connected for formatted stream access, an external file has the following properties:

- Some file storage units of the file may contain record markers; this imposes a record structure on the file in addition to its 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."

Then 9.11.4 says:

"If an end-of-record condition occurs during execution of an input/output statement that contains either an EOR= or IOSTAT= specifier, and an error condition does not occur, then:
...
(4) the file specified in the input statement is positioned after the current record"

This last part is not happening - the file remains positioned before the record marker, causing the program to loop continuously.

I agree that the current behavior is not correct and will let the developers know. Issue ID is DPD200180866.
0 Kudos
IanH
Honored Contributor III
970 Views
The character (if any) returned by the intrinsic, if written to a formatted stream file, acts as a record separator if that file is subsequently read back in as formatted stream. If possible that character must be whatever maps to ASCII LF.

With respect to formatted files, the section 9 part that you quote allows the processor to use a record separator for formatted sequential files that isn't whatever NEW_LINE returns or that is more than one character (like CR-LF), or to use no record separator at all (if it tracks records in some other way). So you can't count on a file written formatted sequential coming back the same way if read formatted stream.

But a newline is always a record separator in formatted stream.

Note we are talking formatted files here. In that case the file storage unit can't practically be anything but a byte on the systems that run ifort or writing ASCII plain text files using formatted sequential would be rather tricky.

File positioning of formatted stream files is defined in terms of records, so for a given file the behaviour should be predictable. Eventually you should be able to get to the end of the file!
0 Kudos
Steven_L_Intel1
Employee
970 Views
This problem has been fixed for a release later this year.
0 Kudos
Reply