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 read(line(startIxs(n):endIxs(n)), *) myArray(n) end do