Best way to read only last two real values in a line using read in Fortran

Here is an attempt, by identifying the tokens without “read(line,*) token”. It uses two simple DO loop scans of the line string.
It first replaces all other delimiters with a blank then searches for the start and end of all tokens. The list of possible delimiters can always change !
It then identifies the start and end of all tokens, testing if the Fortran READ accepts the token as a real number.

This approach does not include some useful free format extensions, such as:

  • the use of , , to identify null tokens
  • the use of arithmentc operators + - / * ^ for sumple numeric calculations.
  • coping with ascii HT char(9)
      character :: line*128
      character :: blank        = ' '
      character :: delimiters*5 = ' ,()='
      character :: list_of_tokens(64)*32
      real      :: list_of_reals(64), val
      integer   :: nt, nr, fc, k, iostat

      line = ' ( v=  1) w = 2.843 unit1 = 5.867 unit2  4.567 1.232 )'
      write ( *,10) 'Initial line :', trim(line)

!   replace other delimiters with blank
      do k = 1, len_trim(line)
        if ( index (delimiters, line(k:k)) > 0 ) line(k:k) = blank
      end do
      write ( *,10) 'Without delim:', trim(line)

!   find all tokens in filtered line
      nt = 0    ! number of tokens
      nr = 0    ! number of reals
      fc = 0    ! first character of next token

      write ( *,10) 'Search for Tokens'
      do k = 1, len_trim(line)+1                ! line must end with a blank

        if ( fc == 0 ) then
          if ( line(k:k) /= blank ) fc = k      ! have start of toktn

        else if ( line(k:k) == blank ) then     ! have end of token
          nt = nt+1
          list_of_tokens(nt) = line(fc:k)       ! add token to list
          read (list_of_tokens(nt), fmt='(f20.0)', iostat=iostat ) val
          if ( iostat == 0 ) then
            nr = nr+1
            list_of_reals(nr) = val             ! add reaL to list
            write ( *,11) nt, trim(list_of_tokens(nt)), '   val =',val
          else
            write ( *,11) nt, trim(list_of_tokens(nt))
          end if
          fc = 0    ! set for start of next token
        end if
      end do

      write ( *,10) 'Summary'
      write ( *,11) nt,'tokens identified'
      write ( *,11) nr,'real values identified'

 10   format (/a,a)
 11   format ( i4,2x,a,a,g10.4 )
      end
1 Like