strtok(3f) - [M_strings:TOKENS] Tokenize a string
(LICENSE:PD)
function strtok(source_string,itoken,token_start,token_end,delimiters) result(strtok_status)
! returned value logical :: strtok_status ! string to tokenize character(len=),intent(in) :: source_string ! token count since started integer,intent(inout) :: itoken ! beginning of token integer,intent(out) :: token_start ! end of token integer,intent(inout) :: token_end ! list of separator characters character(len=),intent(in) :: delimiters
The STRTOK(3f) function is used to isolate sequential tokens in a
string, SOURCE_STRING. These tokens are delimited in the string by
at least one of the characters in DELIMITERS. The first time that
STRTOK(3f) is called, ITOKEN should be specified as zero. Subsequent
calls, wishing to obtain further tokens from the same string,
should pass back in TOKEN_END and ITOKEN until the function result
returns .false.
This routine assumes no other calls are made to it using any other
input string while it is processing an input line.
source_string input string to parse
itoken token count should be set to zero for a new string
delimiters characters used to determine the end of tokens
token_start beginning position in SOURCE_STRING where token was found
token_end ending position in SOURCE_STRING where token was found
strtok_status
Sample program:
program demo_strtok
use M_strings, only : strtok
implicit none
character(len=264) :: inline
character(len=*),parameter :: delimiters=' ;,'
integer :: ios, itoken, istart, iend
do ! read lines from stdin until end-of-file or error
read (unit=*,fmt="(a)",iostat=ios) inline
if(ios /= 0)stop
! must set ITOKEN=0 before looping on strtok(3f)
! on a new string.
itoken=0
do while &
&( strtok(inline,itoken,istart,iend,delimiters) )
print *, itoken,&
& 'TOKEN=['//(inline(istart:iend))//']',istart,iend
enddo
enddo
end program demo_strtok
sample input file
this is a test of strtok; A:B :;,C;;
sample output file
1 TOKEN=[this] 2 5
2 TOKEN=[is] 7 8
3 TOKEN=[a] 10 10
4 TOKEN=[test] 12 15
5 TOKEN=[of] 17 18
6 TOKEN=[strtok] 20 25
7 TOKEN=[A:B] 28 30
8 TOKEN=[:] 32 32
9 TOKEN=[C] 35 35
John S. Urban
Public Domain
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | source_string | |||
integer, | intent(inout) | :: | itoken | |||
integer, | intent(out) | :: | token_start | |||
integer, | intent(inout) | :: | token_end | |||
character(len=*), | intent(in) | :: | delimiters |
FUNCTION strtok(source_string,itoken,token_start,token_end,delimiters) result(strtok_status)
! JSU- 20151030
! ident_14="@(#) M_strings strtok(3f) Tokenize a string"
character(len=*),intent(in) :: source_string ! Source string to tokenize.
character(len=*),intent(in) :: delimiters ! list of separator characters. May change between calls
integer,intent(inout) :: itoken ! token count since started
logical :: strtok_status ! returned value
integer,intent(out) :: token_start ! beginning of token found if function result is .true.
integer,intent(inout) :: token_end ! end of token found if function result is .true.
integer,save :: isource_len
!----------------------------------------------------------------------------------------------------------------------------
! calculate where token_start should start for this pass
if(itoken <= 0)then ! this is assumed to be the first call
token_start=1
else ! increment start to previous end + 1
token_start=token_end+1
endif
!----------------------------------------------------------------------------------------------------------------------------
isource_len=len(source_string) ! length of input string
!----------------------------------------------------------------------------------------------------------------------------
if(token_start > isource_len)then ! user input error or at end of string
token_end=isource_len ! assume end of token is end of string until proven otherwise so it is set
strtok_status=.false.
return
endif
!----------------------------------------------------------------------------------------------------------------------------
! find beginning of token
do while (token_start <= isource_len) ! step thru each character to find next delimiter, if any
if(index(delimiters,source_string(token_start:token_start)) /= 0) then
token_start = token_start + 1
else
exit
endif
enddo
!----------------------------------------------------------------------------------------------------------------------------
token_end=token_start
do while (token_end <= isource_len-1) ! step thru each character to find next delimiter, if any
if(index(delimiters,source_string(token_end+1:token_end+1)) /= 0) then ! found a delimiter in next character
exit
endif
token_end = token_end + 1
enddo
!----------------------------------------------------------------------------------------------------------------------------
if (token_start > isource_len) then ! determine if finished
strtok_status=.false. ! flag that input string has been completely processed
else
itoken=itoken+1 ! increment count of tokens found
strtok_status=.true. ! flag more tokens may remain
endif
!----------------------------------------------------------------------------------------------------------------------------
end function strtok