1 (edited by JohnWasilewski 2013-11-28 11:08:54)

Topic: Fortran question about READ(TxtLN,*)

THIS IS A Q ABOUT FORTRAN,
NOT A Q ABOUT THE SF I.D.E.
-------------------------------------


Can anyone help me with this slightly odd behaviour of FORTRAN?
I suspect the answer is very simple but I just can't see the wood for the trees.

I am trying to do something very simple:

   1.  read a line of data from an input file
        into a text string buffer, and then

   2.  read values from the buffer into a list
        of four INTEGER and one CHAR variables


Here's the code
         :
         INTEGER        IMem,iNode1,iNode2,iMTyp
         CHARACTER   TxtLN*160
         :
         :
         TxtLN=REPEAT(' ',160)

         READ(LU,'(A)') TxtLN
         READ(TxtLN,*) IMem, iNode1, iNode2, iMTyp, Des

Here are some lines of data from the input file
         1, 1, 2, 1,Roof btm chord
         2, 2, 3, 1,Roof btm chord
         3, 0, 0, 0,
         4, 4, 5, 3,Roof btm chord
         5, 5, 6, 3,Roof btm chord

At runtime, the program loops through the code until it detects an EoF, or rather, it is supposed to do so.
What actually happens, however, is that it succeeds on lines 1 and 2 of the data but, as soon as it reaches line 3, it fails.  Line 3 is, just as it seems, an incorrect line of data, and what I am trying to do here is to write code that traps data errors and deals with them.  This is why I am reading each line of data into a text string buffer first.

What happens here is that,
READ(LU,'(A)') TxtLN succeeds, and then
READ(TxtLN,*) IMem, iNode1, iNode2, iMTyp, Des fails.

During runtime, the program simply exits.
During debugging, it just stops and hangs.

I don't understand this at all because I would expect line 3 of the code to be accepted, resulting in data being entered into the variables, of
     IMem=3
     iNode1=0
     iNode2=0
     iMTyp=0
     Des=''  (ie a string of zero length).

I have tried altering the code to this:
         :
         INTEGER        IMem,iNode1,iNode2,iMTyp
         CHARACTER   TxtLN*160
         :
         :
         TxtLN=REPEAT(' ',160)
         READ(LU,'(A)') TxtLN
         TxtLN=TRIM(TxtLN)//REPEAT(' ',160-LEN_TRIM(TxtLN))

         READ(TxtLN,*,ERR=201) IMem,iNode1,iNode2,iMTyp,Des
         GO TO 202

201        CONTINUE ! READ error
              IF(Imem*iNode1*iNode2*iMTyp.NE.0) THEN
                  Des=Repeat(' ',31)
                  GO TO 202 ! ERR now fixed, so continue
              ELSE
                   EXIT
              END IF

202      CONTINUE  !ERR-free or ERR-corrected

This STILL FAILS.  It gets as far as
READ(TxtLN,*,ERR=201) IMem,iNode1,iNode2,iMTyp,Des and then, instead of jumping to the error-trap at 201, it again just dies.

Does anyone have any ideas?
---
John

Re: Fortran question about READ(TxtLN,*)

John,

Use "END=201" in your READ statement, instead of "ERR=201". It will work as expected.

The "END=label" optional argument must be use to detect an End-Of-File error, which is your case.

The "ERR=label" arg should be more appropriate when reading integers or floating point numbers
and you try to detect a corrupted file (e.g. trying to read an integer from a string containing only letters and not digits).

Regards,
Édouard

Re: Fortran question about READ(TxtLN,*)

Very many thanks for that excellent and correct advice.

4 (edited by davidb 2013-11-28 19:45:51)

Re: Fortran question about READ(TxtLN,*)

You don't need to use

TxtLn = REPEAT(" ", 160)

The following will also work since the assignment is automatically padded with spaces.

TxtLn = ""

If you don't want to use ERR= and END= which are essentially a GOTOs, you can use IOSTAT=code, and test for the value of code.

The values are compiler dependent but 0 always means no error, < means end of file,
> 0 means other error.

--
David

Re: Fortran question about READ(TxtLN,*)

Thanks again to both David and Édouard for their good tips.  I knew whole arrays can now be initialised
with a simple Arrayname = 0 but I confess I didn't know that we could also initialise strings in a similar way.

It's great to get such on-the-button help so swiftly,
----
John