# Homepage

Jannis Teunissen

### Reading a variable number of elements in Fortran

The code below locates the content in an input string. The in-arguments are the line to be read in, the maximum number of entries and a string with delimiters. After performing the routine, the out-arguments are the number of entries found, and two list of indices: startIxs(i) holds the starting point of entry i in line, and endIxs(i) holds the end point.

!> Routine to help read a variable number of entries from a line.
! In arguments:
!  line           The line from which we want to read
!  delims         A string with delimiters. For example delims = " ,'"""//char(9)
!                 " ,'"""//char(9) = space, comma, single/double quotation marks, tab
!  nEntriesMax    Maximum number of entries to read in
!
! Out arguments:
!  nEntries       Number of entries found
!  startIxs       On return, startIxs(i) holds the starting point of entry i
!  endIxs         On return, endIxs(i) holds the end point of entry i
subroutine splitLineByDelims(line, delims, nEntriesMax, nEntries, startIxs, endIxs)
character(len=*), intent(in)  :: line, delims
integer, intent(in)           :: nEntriesMax
integer, intent(inout)        :: nEntries, startIxs(nEntriesMax), endIxs(nEntriesMax)

integer                       :: ix, prevIx

prevIx   = 0
nEntries = 0

do while (nEntries < nEntriesMax)

! Find the starting point of the next entry (a non-delimiter value)
ix                   = verify(line(prevIx+1:), delims)
if (ix == 0) exit                      ! No more entries

nEntries             = nEntries + 1
startIxs(nEntries)   = prevIx + ix     ! This is the absolute position in 'line'

! Get the end point of the current entry (next delimiter index minus one)
ix = scan(line(startIxs(nEntries)+1:), delims) - 1

if (ix == -1) then                     ! If there is no last delimiter,
endIxs(nEntries)  = len(line)       ! the end of the line is the endpoint
else
endIxs(nEntries)  = startIxs(nEntries) + ix
end if

prevIx = endIxs(nEntries)              ! We continue to search from here
end do

end subroutine splitLineByDelims

The above routine makes it quite easy to read in a variable amount of numbers. In many cases, this can just be done with the example code below (error checking has been left out for simplicity).

do n = 1, nEntries
end do