fortran90 - Parse random "String + Integers" in Fortran -
say want parse following string:
"compute sum of (integer) , (integer)" in fortran 90, of have no way of telling how large integer be. can 3, 300,000.
as far can tell format statement not leave room inferring size of integer @ run-time. choose large size, i5, number small 3 , program crashes.
how best go this?
if location of integers in string known @ compile time (e.g. 5th , 7th words), can integers directly using list-directed read:
character(256) :: line, words( 50 ) integer :: i1, i2 line = "compute sum of 3 , 30000, get..." read( line, * ) words( 1 : 7 ) !! first 7 words line read( words( 5 ), * ) i1 !! convert 5th , 7th words integer read( words( 7 ), * ) i2 !! i1 = 3, i2 = 30000
but if location of integers not known (e.g. when obtained user input), things more complicated... have written subroutines this, if may seem useful please try :)
module strmod contains subroutine split ( line, words, nw ) implicit none character(*), intent(in) :: line character(*), intent(out) :: words(:) integer, intent(out) :: nw character(len(words)) :: buf( size(words) ) integer :: k, ios nw = 0 ; words(:) = "" k = 1, size(words) read( line, *, iostat=ios ) buf( 1 : k ) if ( ios /= 0 ) exit nw = k words( 1 : nw ) = buf( 1 : nw ) enddo endsubroutine subroutine words_to_ints ( words, ints, ni ) implicit none character(*), intent(in) :: words(:) integer, intent(out) :: ints(:) integer, intent(out) :: ni integer :: k, val, ios ni = 0 ; ints(:) = 0 k = 1, size(words) read( words( k ), *, iostat=ios ) val if ( ios /= 0 ) cycle ni = ni + 1 if ( ni > size(ints) ) stop "size(ints) small" ints( ni ) = val enddo endsubroutine endmodule program main use strmod implicit none character(80) :: line, words( 50 ) !! works size 5 or 7 etc integer :: ints( 50 ), nw, ni, k line = "compute sum of 3 , 30000, 300003 (no!!)" !... note: spaces , commas serve delimiters. better avoid "/". call split ( line, words, nw ) call words_to_ints ( words, ints, ni ) print *, "word counts:", nw k = 1, nw print *, trim( words( k ) ) enddo print *, "int counts:", ni print *, ints( 1 : ni ) end
results:
word counts: 12 compute sum of 3 , 30000 300003 (no!!) int counts: 3 3 30000 300003
Comments
Post a Comment