Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading data file in Fortran with known number of lines but unknown number of entries in each line

Tags:

fortran

How can I read the data file containing known number of lines but the number of entries in each line is unknown, e.g. if my data file contain some thing like

1 3 4 5 6 -7 8 -9

1 3 5 6

4 5 6 7 8 3 5 6 7 8 4 5 7 8

i.e. three lines but the data in each line is unknown. At one time I need the data from one line.

like image 555
Zahur Avatar asked Nov 04 '25 17:11

Zahur


2 Answers

One method: read the line into a string, using a string that is at least as long as the longest expected line. Then you go about parsing the string. E.g., if the numbers are always split by spaces, use that to figure out the substring boundaries. Then you can use "internal reads" to read from each sub-string to obtain the numeric values. An internal read uses a string instead of a unit number and obtains the data from the string -- at least you don't have to recreate the conversion of characters to numeric values, the read statement will do that for you. The intrinsic functions provided with Fortran will make the parsing easier.

like image 129
M. S. B. Avatar answered Nov 07 '25 06:11

M. S. B.


An implementation based on what M. S. B. pointed out. Quite late, but I guess it could be useful to someone.

Have an array of the type you expect to read ready:

double precision, dimension(MAX_NUM_OF_COLS) :: test_array

Read a line from your file:

READ(reading_unit,'(A)',iostat=io) line

Loop and try to read from the line a maximum quantity of numbers:

do i=1,MAX_NUM_OF_COLS
  READ(line, *, iostat=io) test_array(1:i)
  if(io==0) exit
enddo

write(*,*) 'number of columns = ', (i-1)

If needed, loop this over all the lines of your file, and keep the maximum or minimum number of columns.

Minimum example:

integer, parameter :: MAX_NUM_OF_COLS=30
integer, parameter :: MAX_LINE_LENGTH=1000
character(len=MAX_LINE_LENGTH) line
integer i, io, reading_unit
double precision, dimension(MAX_NUM_OF_COLS) :: test_array

reading_unit=100
OPEN(reading_unit, file='the_file')

! Get first line of file.
DO
  READ(reading_unit,'(A)',iostat=io) line
  IF (io/=0) then
    write(*,*) "Error reading file."
    stop
  endif
  exit ! Eventually, do not exit and put the DO loop below here.
ENDDO
CLOSE(reading_unit)

do i=1,MAX_NUM_OF_COLS
  READ(line,*,iostat=io) test_array(1:i)
  if(io==-1) exit
enddo

write(*,*) 'number of columns = ', (i-1)
like image 35
Léo Avatar answered Nov 07 '25 07:11

Léo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!