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

Q about fortran Formatted I/O

WSinc
New Contributor I
568 Views

When I have a READ statement like:

read(2,*)i1,i2,iop,i3,i4,i5,i6

where i1,2,i3,i4,i5,i6  are INTEGER

and iop is character*1

and my input line is:

1 2 / 3 4 5 6

it ignores the remaining part of the line starting with the / character.

So only i1 and i2 get read in.

 

Does a / have a special meaning on an input line?

Is there a way it can be treated the same as any other character?

The reason I am asking, is that the possible choices are : +  -  /  and *

The other choices read in normally. Maybe this is discussed in detail somewhere?

0 Kudos
4 Replies
IanH
Honored Contributor III
568 Views

You are using list directed formatting (using a * for the format specifier) and that mode of formatting has a few surprises like this.  As you've found, a slash terminates input processing.  Other symbols also have special meaning, including *.

You can find the compilers documentation for list directed input here - https://software.intel.com/en-us/node/525605#D663F2A6-A4EC-443F-A47D-C43C18906801

I think a reasonable rule is to not use list directed formatting for general input processing - it is really only appropriate when the input (and the source code for input processing) has specifically been written to accommodate its eccentricities, or you don't care if things go wrong.  Instead, if you have a free form of input, read the entire line in and parse it yourself manually using whatever specific rules you decide apply for that input.

0 Kudos
WSinc
New Contributor I
568 Views

But I also noticed this when I use a Format statement.

For example:

character*1 iop(18)

read(1,100)iop

100 format(18(a1,1x))

where the input line is:

* - / + + / * - + - / * + - / *  + + + + + +

In this case I am not using a * for the format statement.

 

0 Kudos
IanH
Honored Contributor III
568 Views

Your example string, as presented, has two spaces between the last * and the next +.  The number of symbols is also different to the size of the array.

PROGRAM io
  IMPLICIT NONE
  
  ! The string to test.
  CHARACTER(*), PARAMETER :: test_string  &
  !      1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 ....
      = '* - / + + / * - + - / * + - / *  + + + + + +'
  !                                      ^
  !                                      |
  !                                      |
  !    Look very carefully here  --------+
  
  ! The filename for the test input.
  CHARACTER(*), PARAMETER :: test_file = '2014-10-29 io.txt'
  
  INTEGER :: unit             ! Unit for input and output.
  CHARACTER :: iop(18)        ! Test buffer.
  INTEGER :: i                ! Array index.
  
  !*****************************************************************************
  
  ! Create the test file.
  OPEN(NEWUNIT=unit, FILE=test_file, ACTION='WRITE')
  WRITE (unit, "(A)") test_string
  CLOSE(unit)
  
  ! Read it back in.
  OPEN(NEWUNIT=unit, FILE=test_file, ACTION='READ')
  READ (unit, "(18(A1,1X))") iop
  CLOSE(unit)
  
  ! Print results.
  PRINT "(*(I0,T10,'""',A,'""',:,/))", (i, iop(i), i = 1, SIZE(iop))
  
END PROGRAM io

 

0 Kudos
John_Campbell
New Contributor II
568 Views

You could try:

1 2 "/" 3 4 5 6

0 Kudos
Reply