norio
norio

Reputation: 3882

Fortran read statement reading beyond an end of line

do you know if the following statement is guaranteed to be true by one of the fortran 90/95/2003 standards? "Suppose a read statement for a character variable is given a blank line (i.e., containing only white spaces and new line characters). If the format specifier is an asterisk (*), it continues to read the subsequent lines until a non-blank line is found. If the format specifier is '(A)', a blank string is substituted to the character variable."

For example, please look at the following minimal program and input file.

program code:

PROGRAM chk_read
  INTEGER,         PARAMETER :: MAXLEN=30
  CHARACTER(len=MAXLEN)      :: str1, str2

  str1='minomonta'
  read(*,*)     str1
  write(*,'(3A)')  'str1_start|', str1, '|str1_end'

  str2='minomonta'
  read(*,'(A)') str2
  write(*,'(3A)')  'str2_start|', str2, '|str2_end'

END PROGRAM chk_read

input file:

----'input.dat' content is below this line----

yamanakako

kawaguchiko    
----'input.dat' content is above this line----

Please note that there are four lines in 'input.dat' and the first and third lines are blank (contain only white spaces and new line characters). If I run the program as

$ ../chk_read < input.dat > output.dat 

I get the following output

----'output.dat' content is below this line----
str1_start|yamanakako                    |str1_end
str2_start|                              |str2_end
----'output.dat' content is above this line----

The first read statement for the variable 'str1' seems to look at the first line of 'input.dat', find a blank line, move on to the second line, find the character value 'yamanakako', and store it in 'str1'.

In contrast, the second read statement for the variable 'str2' seems to be given the third line, which is blank, and store the blank line in 'str2', without moving on to the fourth line.

I tried compiling the program by Intel Fortran (ifort 12.0.4) and GNU Fortran (gfortran 4.5.0) and got the same result.

A little bit about a background of asking this question: I am writing a subroutine to read a data file that uses a blank line as a separator of data blocks. I want to make sure that the blank line, and only the blank line, is thrown away while reading the data. I also need to make it standard conforming and portable.

Thanks for your help.

Upvotes: 6

Views: 8143

Answers (2)

milancurcic
milancurcic

Reputation: 6241

From Fortran 2008 standard draft:

List-directed input/output allows data editing according to the type of the list item instead of by a format specification. It also allows data to be free-field, that is, separated by commas (or semicolons) or blanks.

Then:

The characters in one or more list-directed records constitute a sequence of values and value separators. The end of a record has the same effect as a blank character, unless it is within a character constant. Any sequence of two or more consecutive blanks is treated as a single blank, unless it is within a character constant.

This implicitly states that in list-directed input, blank lines are treated as blanks until the next non-blank value.

When using a fmt='(A)' format descriptor when reading, blank lines are read into str. On the other side, fmt=*, which implies list-directed I/O in free-form, skips blank lines until it finds a non-blank character string. To test this, do something like:

PROGRAM chk_read
INTEGER :: cnt
INTEGER,         PARAMETER :: MAXLEN=30
CHARACTER(len=MAXLEN)      :: str

cnt=1
do
  read(*,fmt='(A)',end=100)str
  write(*,'(I1,3A)')cnt,' str_start|', str, '|str_end'
  cnt=cnt+1
enddo
100 continue

END PROGRAM chk_read

$ cat input.dat



yamanakako

kawaguchiko

EOF

Running the program gives this output:

$ a.out < input.dat 
1 str_start|                              |str_end
2 str_start|                              |str_end
3 str_start|                              |str_end
4 str_start|yamanakako                    |str_end
5 str_start|                              |str_end
6 str_start|kawaguchiko                   |str_end

On the other hand, if you use default input:

read(*,fmt=*,end=100)str

You end up with this output:

$ a.out < input.dat 
1 str1_start|yamanakako                    |str1_end
2 str2_start|kawaguchiko                   |str2_end

Upvotes: 3

This Part of the F2008 standard draft probably treats your problem:

10.10.3 List-directed input

7 When the next effective item is of type character, the input form consists of a possibly delimited sequence of zero or more rep-char s whose kind type parameter is implied by the kind of the effective item. Character sequences may be continued from the end of one record to the beginning of the next record, but the end of record shall not occur between a doubled apostrophe in an apostrophe-delimited character sequence, nor between a doubled quote in a quote-delimited character sequence. The end of the record does not cause a blank or any other character to become part of the character sequence. The character sequence may be continued on as many records as needed. The characters blank, comma, semicolon, and slash may appear in default, ASCII, or ISO 10646 character sequences.

Upvotes: 2

Related Questions