geeb.24
geeb.24

Reputation: 557

Fortran Print Line Number While Reading Input File

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

This is the error I get:

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

Which means that the code is getting hung up on some line in my input file that doesn't correspond with the above format.

Here is the part of my code where Fortran is reading 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'd like to add a line in the above piece of code to identify the current line the code is reading, so that when it gets hung up, I'll know which line contains the error. Thank you for your help.

Here's what I tried and it's giving 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

Upvotes: 3

Views: 1366

Answers (2)

innoSPG
innoSPG

Reputation: 4656

Add an explicit loop to read your data like:

      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 will know exactly where it stopped thank to the write statement in the reading loop. Note that I added two new labels, 20 to control the new loop 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

Upvotes: 2

francescalus
francescalus

Reputation: 32406

With a read statement like

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

an error in the input results in (error) termination of the program. One has no control over this termination, and in particular one can't do further processing.

There are two ways to avoid this termination, and both involve using an additional specifier in the read statement. One is iostat= and the other err=. If either of these is present then an error doesn't result in termination.

With iostat (for integer istat):

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

then on an error condition, istat will have a (processor-dependent) positive value. It will be zero when (and only when) there is no error.

With err (for some label, say, 991):

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

Putting all that together, let's 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 that code like it really was 1980.]

Upvotes: 4

Related Questions