chomp(3f) - [M_strings:TOKENS] Tokenize a string, consuming it one
token per call
(LICENSE:PD)
function chomp(source_string,token[,delimiters])
character(len=*) :: source_string
character(len=:),intent(out) :: token
character(len=:),intent(in),optional :: delimiters
integer :: chomp
The CHOMP(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. This routine consumes the
source_string one token per call. It returns -1 when complete. The
default delimiter list is "space,tab,carriage return,newline".
SOURCE_STRING string to tokenize
DELIMITERS list of separator characters
TOKEN returned token
CHOMP status flag. 0 = success, -1 = no tokens remain
Sample program:
program demo_chomp
use M_strings, only : chomp
implicit none
character(len=100) :: inline
character(len=:),allocatable :: token
character(len=*),parameter :: delimiters=' ;,'
integer :: ios
integer :: icount
integer :: itoken
icount=0
do ! read lines from stdin until end-of-file or error
read (unit=*,fmt="(a)",iostat=ios) inline
if(ios /= 0)stop
icount=icount+1
itoken=0
write(*,*)'INLINE ',trim(inline)
do while ( chomp(inline,token,delimiters) >= 0)
itoken=itoken+1
print *, itoken,'TOKEN=['//trim(token)//']'
enddo
enddo
end program demo_chomp
sample input file
this is a test of chomp; A:B :;,C;;
sample output file
> INLINE this is a test of chomp; A:B :;,C;;
> 1 TOKEN=[this]
> 2 TOKEN=[is]
> 3 TOKEN=[a]
> 4 TOKEN=[test]
> 5 TOKEN=[of]
> 6 TOKEN=[chomp]
> 7 TOKEN=[A:B]
> 8 TOKEN=[:]
> 9 TOKEN=[C]
John S. Urban
Public Domain
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*) | :: | source_string | ||||
character(len=:), | intent(out), | allocatable | :: | token | ||
character(len=*), | intent(in), | optional | :: | delimiters |
FUNCTION chomp(source_string,token,delimiters)
! ident_9="@(#) M_strings chomp(3f) Tokenize a string JSU- 20151030"
character(len=*) :: source_string ! string to tokenize
character(len=:),allocatable,intent(out) :: token ! returned token
character(len=*),intent(in),optional :: delimiters ! list of separator characters
integer :: chomp ! returns copy of shifted source_string
character(len=:),allocatable :: delimiters_local
integer :: token_start ! beginning of token found if function result is .true.
integer :: token_end ! end of token found if function result is .true.
integer :: isource_len
!-----------------------------------------------------------------------------------------------------------------------------------
! calculate where token_start should start for this pass
if(present(delimiters))then
delimiters_local=delimiters
else ! increment start to previous end + 1
delimiters_local=char(32)//char(09)//char(10)//char(13) ! space,horizontal tab, newline, carriage return
endif
!-----------------------------------------------------------------------------------------------------------------------------------
isource_len=len(source_string) ! length of input string
!-----------------------------------------------------------------------------------------------------------------------------------
! find beginning of token
token_start=1
do while (token_start <= isource_len) ! step thru each character to find next delimiter, if any
if(index(delimiters_local,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_local,source_string(token_end+1:token_end+1)) /= 0) then ! found a delimiter in next character
exit
endif
token_end = token_end + 1
enddo
!write(*,*)'TOKEN_START ',token_start
!write(*,*)'TOKEN_END ',token_end
chomp=isource_len-token_end
if(chomp >= 0)then
token=source_string(token_start:token_end)
source_string=source_string(token_end+1:)
else
token=''
source_string=''
endif
!-----------------------------------------------------------------------------------------------------------------------------------
end function chomp