Stefano Zaghi <
stefan...@gmail.com> schrieb:
> Il giorno lunedì 12 febbraio 2018 11:35:56 UTC+1, Thomas Koenig ha scritto:
>> Beliavsky <
beli...@aol.com> schrieb:
>> > On Sunday, February 11, 2018 at 10:17:12 AM UTC-5, Thomas Koenig wrote:
>> >> Nasser M. Abbasi <
n...@12000.org> schrieb:
>> >>
>> >> > Are you saying Fortran does not have a String Split build-in
>> >> > intrinsic function as many languages these days do.
>> >> > In Mathematica
>> >> >
>> >> > str = "1,10,123,15,654,12";
>> >> > ToExpression@StringSplit[str,","]
>> >>
>> >> For comma separation, quite easy:
>> >>
>> >> program main
>> >> integer, dimension(6) :: a
>> >> character(len=:), allocatable :: str
>> >> str = "1,10,123,15,654,12"
>> >> read (unit=str,fmt=*) a
>> >> print *,a
>> >> end program main
>> >
>> > Usually you don't know into how many strings the initial string will be split. Your example assumes you do know.
>>
>> The following code took me less than five minutes to write:
[...]
> Dear Thomas,
>
> I agree with you that this was a simple task achieved in few
> minutes, but it results also into a somehow not flexible/robust
> method, i.e. it does not work with "=" as separator
See below.
>or with real
> values.
Now, that is _really_ easy to change :-)
>I agree with Clive and others, Fortran standard is lacking
>when string support is concerned.
Maybe.
The code below took a little longer to write, but that was mostly
because I wanted to have the lookup table as a parameter for reasons
of efficiency, and had to make sure of the MERGE syntax.
Now, as an excercise for the reader, modify this so that
it takes an optional argument to indicate if several adjacent
separators should be counted a a single one.
module split
implicit none
character(len=2), parameter :: sep = ",="
integer, private :: ii
logical, parameter, private, dimension(0:255) :: &
fld = merge(.true.,.false., [(index(sep,achar(ii))>0,ii=0,255)])
private :: is_sep
contains
subroutine split_read_int(str, a)
character(len=*), intent(in) :: str
integer, dimension(:), allocatable :: a
integer :: n,i
integer :: from, to, mylen
n = 1
mylen = len_trim(str)
do i=1, mylen
if (is_sep(str(i:i))) n = n + 1
end do
allocate (a(n))
n = 1
from = 0
to = 1
do while (to <= mylen)
if (is_sep(str(to:to))) then
read (unit=str(from+1:to-1),fmt=*) a(n)
n = n + 1
from = to
end if
to = to + 1
end do
read (unit=str(from+1:mylen),fmt=*) a(n)
end subroutine split_read_int
logical function is_sep(c)
character(len=1), intent(in) :: c
is_sep = fld(ichar(c(1:1)))
end function is_sep
end module split
program main
use split
implicit none
integer, allocatable, dimension(:) :: a
character(len=50) :: str = "1,24,5=6"
integer :: i