user949814
user949814

Reputation:

FORTRAN 77 Simple input/out

I am new to FORTRAN, and must write a FORTRAN 77 program to read the following format from a file redirection or standard input:

[CHARACTER] [REAL] [REAL] [REAL] ... (can have any number of these)
D [INTEGER] (only one of these)
[REAL] [REAL] [REAL] ... (can have any number of these)

example input could be:

T 1.0 2.0 3.0
S 1.0 2.0 4.0
Y 3.0 4.0 5.0
D 2
3.0 5.0 6.0
4.5 4.6 5.6

My native language is C++, so I'm new to this whole idea of a read statement going to the next line automatically.

So far, I have the following code:

c234567
      character*1 D
      character*1 LETTER
      real X, Y, Z
      integer lines
      real point1, point2, point3

85 format (3F10.6) 100 format (A1, 5X, F10.6, 5X, F10.6, 4X, F10.6) 990 format (A, I10)

      MAX = 6
      LETTER = 'Z'
      D = 'D'

      read *, LETTER, X, Y, Z

10 if(LETTER .ne. D) then write (6, 100) LETTER, X, Y, Z read *, LETTER, X, Y, Z goto 10 else goto 20 endif

C ===================================================== 20 lines = aint(X) write (*,990) 'LINES: ', lines write (6, 85) X, Y, Z read *, Z write (6, 85) X, Y, Z end

As you can see, I get the first portion of the input fine, but after that it kind of all goes to mush because of the read statement: read*, Z going to the next line. In my specific input file provided above, I get the 2 after the D, and the next two values (3.0, 5.0) but I skip the 6.0

Any help would be great. Thanks.

Upvotes: 2

Views: 3700

Answers (2)

I haven't even looked at you code but I would suggest a strategy like this

(1) read the initial character of the line
if not "D" then 
    read reals
    store the line
    loop to (1)
else
    read one integer
    store the line
    break
endif
read lines of reals until end-of-file

My fortran is very rusty, but I believe that there are constructs that will help you with this. Certainly the END modifier to READ is going to be helpful with the last bit.


After a little experimenting, I find that gfortran seems to support the old trailing $ for non-advancing input convention and advance='no'. However, g77 does not. I can't speak to any other compiler--as far as I know this was never standardized until fortran 90 where advance='no' was introduced.

Demo code that works in gfortran, but not in g77

      program temp
c234567
      character a
      integer i
      real x, y, z, w(50)

c This or with (*,'(A1 $)')
      read (*,'(A1)',advance='no') a

      if (a .eq. 'D') then
         read (*,*) i
         write (*,*) a, i
      endif

      end

This should be enough to make the incremental strategy work if you compiler supports non-advancing input somehow.

The alternative is to read the letter plus the rest of the line into a large character buffer, then parse the buffer separately along the lines of

      character a, buf(1024)
      read (*,'(a1, a1024)') a, buf
      if (a .eq. d) then
         read (buf,*) i
      endif

Upvotes: 0

alexurba
alexurba

Reputation: 1664

If you know that your lines will never exceed a maximum length, I suggest to read the whole line and then to parse the line according to your rules.

An example using a maximum line length of 1024 characters:

       CHARACTER*1024 line
       CHARACTER letter
100    FORMAT (A)
       READ(*,100) line
       READ(line, *) letter
       IF (letter .eq. 'T') THEN
          ...
       END IF

Maybe this technique works for you.

Upvotes: 3

Related Questions