Fortran print line number when reading input file

I am getting a formatting error from an input file and I would like to determine where the formatting error occurs in the input file.
My question is, is there a way to print the line number of the input file where the error occurs in my fortran code?

This is the error I am getting:

fmt: read unexpected character
apparent state: unit 4 named input_file
last format: (6(I3,X,F7.2,X,I2,X))
lately reading sequential formatted external IO

      

This means that the code is hanging on some line in my input file that does not follow the format above.

Here is the portion of my code where Fortran reads in the input file:

      DO 20  K  = 1,NUMB
      READ(4,200)  (NSTN(J),TT(J),IKPS(J),J=1,6)
      DO 30 J   = 1,6
      L         = L+1
      ISTO(L,N) = NSTN(J)
      SECT(L,N) = TT(J)
      KWV(L,N)  = IKPS(J)
30    CONTINUE
20    CONTINUE
      KOBS(N)   = NSTM
10    CONTINUE
100   FORMAT(5(I2,X),F6.2,X,F5.2,X,F7.3,X,F6.3,X,F8.3,X,F6.3,
     &       X,F6.2,X,F5.2,X,I3,X,F4.1,X,F5.2,X,F7.3) 
200   FORMAT(6(I3,X,F7.2,X,I2,X))
      RETURN
      END

      

I would like to add a line in the above code snippet to identify the current line that the code is reading, so that when it hangs up I know which line contains the error. Thank you for your help.

Here's what I tried and it gave me another error:

c      READ(4,200)  (NSTN(J),TT(J),IKPS(J),J=1,6)
  READ(4,200)line
  READ(line,*,iostat=ios) (NSTN(J),TT(J),IKPS(J),J=1,6)
  IF(ios>0)THEN
  WRITE(*,*)'Error Reading Line',line
  STOP
  ENDIF
  INTEGER ios
  CHARACTER*(200)line

      

+3


source to share


2 answers


Add an explicit loop to read your data, for example:

      DO 20 J = 1,6
      write (*,*) 'Reading line = ', J
      READ(4,100)  NSTN(J),TT(J),IKPS(J)
20    CONTINUE

100   FORMAT(I3,X,F7.2,X,I2,X)

      

This way, you know exactly where it left off thanks to the write-write in the read loop. Note that I have added two new labels, 20 for the new loop control and 100 for the new format statement. Adapt accordingly.



==============

      DO 20  K  = 1,NUMB
      WRITE (*,*) 'Reading line = ', K
      READ(4,200)  (NSTN(J),TT(J),IKPS(J),J=1,6)
      DO 30 J   = 1,6
      L         = L+1
      ISTO(L,N) = NSTN(J)
      SECT(L,N) = TT(J)
      KWV(L,N)  = IKPS(J)
30    CONTINUE
20    CONTINUE
      KOBS(N)   = NSTM
200   FORMAT(6(I3,X,F7.2,X,I2,X))
      RETURN
      END

      

+2


source


With a read instruction like

      READ(4,200)  (NSTN(J),TT(J),IKPS(J),J=1,6)

      

an error in the input results in the termination (error) of the program. One of them has no control over this termination and, in particular, it cannot perform further processing.

There are two ways to avoid this termination, and both involve the use of an extra specifier in the read statement. One of them is iostat=

and the other err=

. If one of them is present, then the error does not terminate.

C iostat

(for integers istat

):

      READ(4,200,iostat=istat)  (NSTN(J),TT(J),IKPS(J),J=1,6)

      

then under error condition istat

will have a (processor-dependent) positive value. It will be zero when (and only then) no error occurs.



C err

(for some label, say 991

):

      READ(4,200,err=991)  (NSTN(J),TT(J),IKPS(J),J=1,6)

      

Putting it all together, imagine an outer loop

      DO 100 LINE=1,91959
        READ(4,200,IOSTAT=ISTAT) (NSTN(J),TT(J),IKPS(J),J=1,6)
        IF (ISTAT.NE.0) THEN
          PRINT *, 'It went wrong on line', LINE
          STOP
        END IF
        ...
100   CONTINUE

      

or

      DO 100 LINE=1,91959
        READ(4,200,ERR=991) (NSTN(J),TT(J),IKPS(J),J=1,6)
        ...
 100  CONTINUE
      ...
 991  PRINT *, 'It went wrong on line', LINE
      STOP

      

[I couldn't bring myself to write this code like I did in 1980.]

+4


source







All Articles