Roloka
Roloka

Reputation: 191

How to read the lines of the input in arbitrary order?

I would like to ask how I can read the lines of the input in arbitrary order. In other words: how to read a given line of the input? I have written the next test program:

  program main
  implicit integer*4(i-n)
  dimension ind(6)
  do i=1,6
     ind(i)=6-i
  end do
  open(7,file='test.inp',status='old')
  do i=0,5
     call fseek(7,ind(i+1),0)
     read(7,*) m
     write(*,*) m
     call fseek(7,0,0)
  end do
  end

where test.inp contains:

1
2
3
4
5
6

My output given is:

4
5
6
2
3
4

What is the problem? I would expect

6
5
4
3
2
1

Upvotes: 1

Views: 135

Answers (1)

agentp
agentp

Reputation: 6989

for a text file the simplest thing is to just use an empty read to advance lines. This will read the nth line of file opened with unit=iu

       rewind(iu)
       do i=1,n-1
       read(iu,*)
       enddo
       read(iu,*)data

Note if you are doing a bunch of reads from the same file you should consider reading the whole file into a character array, then you can very simply access lines by index.

here is an example of reading in a whole file:

  implicit none
  integer::iu=20,i,n,io
  character(len=:),allocatable::line(:)
  real::x,y
  open(iu,file='filename')
  n=0
  do while(.true.) ! pass through once to count the lines
     read(iu,*,iostat=io)
     if(io.ne.0)exit
     n=n+1
  enddo
  write(*,*)'lines in file=',n
  !allocate the character array. Here I'm hard coding a max line length
  !of 130 characters (that can be fixed if its a problem.)
  allocate(character(130)::line(n))      
  rewind(iu)
  !read in entire file
  do i=1,n 
     read(iu,'(a)')line(i)
  enddo
  !now we can random access the lines using internal reads:
  read(line(55),*)x,y
  ! ( obviously use whatever format you need on the read )
  write(*,*)x,y
  end

One obvious drawback to this is you can not read data that spans multiple lines the same as if you were reading from the file.

Edit: my old version of gfortran doensn't like that allocatable character syntax. This works:

 character(len=130),allocatable::line(:)
  ...
 allocate(line(n))

Upvotes: 1

Related Questions