I have tried to read the following text file using Fortran. The text file has 24 rows and 15 columns. I want to put all the data in a single column array z. I wanted to read the 1st column then the 2nd then 3rd until the end. Here is my data:
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0.16 0.16 0.17 0.18 0.19 0.19 0.19 0.19 0.18 0.18 0.18 0.18
0 0 0 0.31 0.33 0.35 0.37 0.37 0.39 0.39 0.37 0.37 0.37 0.37 0.37
0 0 0 0.47 0.49 0.52 0.55 0.56 0.58 0.58 0.56 0.55 0.55 0.55 0.55
0 0 0 0.48 0.51 0.55 0.59 0.6 0.61 0.61 0.59 0.59 0.59 0.59 0.59
0 0 0 0.48 0.53 0.57 0.62 0.63 0.64 0.63 0.62 0.62 0.62 0.62 0.62
10 34 0 0.49 0.55 0.6 0.66 0.68 0.69 0.68 0.67 0.67 0.67 0.67 0.67
0 0 0 0.49 0.57 0.63 0.7 0.72 0.73 0.73 0.72 0.72 0.72 0.72 0.72
0 0 0 0.49 0.59 0.65 0.75 0.77 0.78 0.77 0.77 0.77 0.77 0.77 0.77
0 0 0 0.49 0.61 0.68 0.79 0.81 0.83 0.82 0.81 0.82 0.82 0.82 0.82
0 0 0 0.49 0.63 0.7 0.83 0.86 0.87 0.87 0.86 0.87 0.87 0.87 0.87
0 0 0 0.49 0.65 0.73 0.87 0.9 0.92 0.92 0.91 0.92 0.92 0.92 0.92
0 0 0 0.49 0.67 0.76 0.91 0.95 0.97 0.96 0.95 0.97 0.97 0.97 0.97
0 0 0 0.49 0.69 0.78 0.95 0.99 1.01 1.01 1 1.02 1.02 1.02 1.02
0 0 0 0.49 0.71 0.81 0.99 1.04 1.06 1.06 1.05 1.07 1.07 1.07 1.07
0 0 0 0.49 0.73 0.83 1.04 1.08 1.11 1.1 1.09 1.11 1.11 1.11 1.11
0 0 0 0.49 0.75 0.86 1.08 1.13 1.15 1.15 1.14 1.16 1.16 1.16 1.16
0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21
0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21
0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21
24 48 72 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21
Here is the code I tried:
program readdata
use, intrinsic :: iso_fortran_env
implicit none
integer :: i, j, k
real :: z(360)
integer :: iostat
character(len=255) :: filename
! Set the text file name
filename = 'D:/Shuvashish/Oyster Shaye/growth_z_for_sal_tem.txt'
! Open the text file
open(15, file=filename, status='old',form='formatted')
! Read the data from the text file into the z array
k = 1
do j = 1, 15 ! j is changing
do i = 1, 24 ! when j=2 and k=25, iostat becomes -1
read(15,*,iostat=iostat) z(k)
if (iostat < 0) exit ! exit loop if iostat is negative
k = k + 1
end do
end do
! Close the text file
close(15)
! Print the values of z
do k = 1, 360
print*, z(k)
end do
end program readdata
Whenever, the loop finishes reading the last element of the 1st column, iostat
becomes -1 and after that the it doesn't read the other columns. I am an absolute begineer in Fortran. Please let me know how to make the code work. Thanks.
When you write
read(15,*,iostat=iostat) z(k)
you will actually read an entire row ... but you will discard all but the first element. Thus, you can only do this 24 times and you will end up only storing the first column.
But when we read or write text we read from left to right (apologies to Leonardo da Vinci and anybody else writing from right to left!) and do so line by line. Similarly for computer files.
So, if you insist on reading into a 1-d array, (actually, you might find life easier if you read into a 2-d array), then read it ROW-BY-ROW first, then "transpose" to COLUMN-BY-COLUMN afterwards. (To be honest, do you really have to store your data column by column? You could easily have the i index denoting a column rather than a row.)
To read that file and subsequently store it in a 1-d array as first column, followed by second column, followed by third column etc, try the following.
program readdata
implicit none
integer, parameter :: ni = 24, nj = 15
character(len=*), parameter :: filename = "input.txt"
integer i, j
real rowByRow(ni*nj), columnByColumn(ni*nj)
! Read the text file ROW-BY-ROW
open( 15, file=filename )
read( 15, * ) rowByRow
close( 15 )
! Transpose it to store COLUMN-BY-COLUMN
do j = 1, nj
columnByColumn( (j-1)*ni+1 : j*ni ) = rowByrow( j : : nj )
end do
! Test write
j = 5
print "( a, i0 )", "Column ", j
print "( f5.2 )", columnByColumn( (j-1)*ni + j : j*ni )
end program readdata
For example, the 5th column:
Column 5
0.16
0.33
0.49
0.51
0.53
0.55
0.57
0.59
0.61
0.63
0.65
0.67
0.69
0.71
0.73
0.75
0.77
0.77
0.77
0.77