James
James

Reputation: 105

Adapting a Fortran Code to write a file, run an executable and read in arrays from a file

I am new to Fortran but I am trying to adapt a Fortran code and I am having trouble doing something which I think is probably quite simple.

I want to adapt a Fortran file called original.f so that it makes an input file called input.inp and populates it with 4 integers calculated earlier in original.f so that input.inp looks like, for example:

    &input
        A = 1
        B = 2
        C = 3
        D = 4
    &end

I know how to write this format:

    OPEN(UNIT=10,FILE='input.inp')
    WRITE (10,00001) 1,2,3,4
    ...
    ...
    ...
    00001 Format (/2x,'&input',
         &        /2x,'A = ',i4,
         &        /2x,'B = ',i4,
         &        /2x,'C = ',i4,
         &        /2x,'D = ',i4,
         &        /2x,'&end')

(or something like this that I can fiddle with when I get it working) but I am not sure how to create the input.inp file write this into it and then use this input file.

The input file needs to be used to run an executable called "exec". I would run this in bash as:

    ./exec < input.inp > output.out

Where output.out contains two arrays called eg(11) and ai(11,6,2) (with dimensions given) like:

    eg(1)= 1
    eg(2)= 2
    ...
    ...
    ...
    eg(11)= 11
    ai(1,1,1)= 111
    ai(1,2,1)= 121
    ...
    ...
    ...
    ai(11,6,2)=1162

Finally I need to read these inputs back into original.f so that they can be used further down in file. I have defined these arrays at the beginning of original.f as:

    COMMON /DATA  / eg(11),ai(11,6,2)

But I am not sure of the Fortran to read data line by linw from output.out to populate these arrays.

Any help for any of the stages in this process would be hugely appreciated.

Thank you very much

James

Upvotes: 1

Views: 1070

Answers (2)

sigma
sigma

Reputation: 2953

If I understand the expanded question correctly, you have to work with an output file, produced by some other code you did not write, with lines like eg(1) = ....

For the simplest case where you know the number of elements and their ordering beforehand, you can simply search each line for the equals sign from behind:

program readme
  implicit none
  character(100) :: buffer
  integer :: i, j, k, pos, eg(11), ai(11,6,2)

  do i = 1,11
    read*, buffer
    pos = index(buffer, '=', back = .true.)
    read(buffer(pos+1:), *) eg(i)
  enddo

  ! I have assumed an arbitrary ordering here
  do k = 1,2
    do i = 1,11
      do j = 1,6
        read*, buffer
        pos = index(buffer, '=', back = .true.)
        read(buffer(pos+1:), *) ai(i,j,k)
      enddo
    enddo
  enddo 
end program

Assuming here for simplicity that the data are provided to standard input.

Upvotes: 0

Fortranner
Fortranner

Reputation: 2605

Since you have shown how you create the input file, I assume the question is how to read it. The code shows how "a" and "b" can be read from successive lines after skipping the first line. On Windows, if the resulting executable is a.exe, the commands a.exe < data.txt or type data.txt | a.exe will read from data.txt.

program xread
implicit none
character (len=10) :: words(3)
integer, parameter :: iu = 5 ! assuming unit 5 is standard input
integer            :: a,b
read (iu,*) ! skip line with &input
read (iu,*) words ! read "a", "=", and "1" into 3 strings
read (words(3),*) a ! read integer from 3rd string
read (iu,*) words ! read "b", "=", and "1" into 3 strings 
read (words(3),*) b ! read integer from 3rd string
print*,"a =",a," b =",b
end program xread

Upvotes: 1

Related Questions