Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(string), | intent(out) | :: | dtv | The string. |
||
integer, | intent(in) | :: | unit | Logical unit. |
||
character(kind=CK,len=1), | intent(in) | :: | delim | String delimiter. |
||
integer, | intent(out) | :: | iostat | IO status code. |
||
character(kind=CK,len=*), | intent(inout) | :: | iomsg | IO status message. |
Read a delimited string from a unit connected for formatted input.
If the closing delimiter is followed by end of record, then we return end of record.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
character(kind=CK,len=1), | public | :: | ch | A character read. |
|||
logical, | public | :: | was_delim | Indicates that the last character read was a delimiter. |
subroutine read_delimited(dtv, unit, delim, iostat, iomsg)
!---------------------------------------------------------------------------------------------------------------------------------
!< Read a delimited string from a unit connected for formatted input.
!<
!< If the closing delimiter is followed by end of record, then we return end of record.
!---------------------------------------------------------------------------------------------------------------------------------
class(string), intent(out) :: dtv !< The string.
integer, intent(in) :: unit !< Logical unit.
character(kind=CK, len=1), intent(in) :: delim !< String delimiter.
integer, intent(out) :: iostat !< IO status code.
character(kind=CK, len=*), intent(inout) :: iomsg !< IO status message.
character(kind=CK, len=1) :: ch !< A character read.
logical :: was_delim !< Indicates that the last character read was a delimiter.
!---------------------------------------------------------------------------------------------------------------------------------
!---------------------------------------------------------------------------------------------------------------------------------
was_delim = .false.
dtv%raw = ''
do
read(unit, "(A)", iostat=iostat, iomsg=iomsg) ch
if (is_iostat_eor(iostat)) then
if (was_delim) then
! end of delimited string followed by end of record is end of the string. Pass back the end of record condition to the
! caller
return
else
! end of record without terminating delimiter - move along
cycle
endif
elseif (iostat /= 0) THEN
return
endif
if (ch == delim) then
if (was_delim) then
! doubled delimiter is one delimiter in the value
dtv%raw = dtv%raw // ch
was_delim = .false.
else
! need to test next character to see what is happening
was_delim = .true.
endif
elseif (was_delim) then
! the previous character was actually the delimiter for the end of the string. Put back this character
read(unit, "(TL1)", iostat=iostat, iomsg=iomsg)
return
else
dtv%raw = dtv%raw // ch
endif
enddo
return
!---------------------------------------------------------------------------------------------------------------------------------
endsubroutine read_delimited