Search code examples
inputfortranfortran77

fortran 77 take string from input until space like input.next() in java


I am a newbie on Fortran 77. I need a code that like input.next() in Java. I want to give an input like "hi how are you today" and check every word one by one, so to do that, i need to take words one by one. What is the simplest way to do it? I can check every character and put characters before space in a character variable but it looks hard way.


Solution

  • Although this is probably a duplicate, here is what I have in hand (to show that there is no direct builtin routine, and although it may appear tricky at first sight, it is not that "hard" to write it somehow...) I think there are also more efficient ways based on index() function. If necessary, it may be useful to write a similar routine like "input_next()" to get the next word one-by-one [*].

    program main
        implicit none
        character(100) line, words( 100 )
        integer n, i
    
        line = "hi how are you today"   ! input string
        words = ""                      ! words to be obtained
    
        call split_str( line, words, n )
    
        do i = 1, n
            print *, "i= ", i, "word= ", trim(words( i ))
        enddo
    end
    
    subroutine split_str( line, words, n )
        implicit none
        character(*), intent(in)  :: line
        character(*), intent(out) :: words(*)
        integer,      intent(out) :: n
        integer :: ios
        character(100) :: buf( 100 )  ! large buffer
    
        n = 0
        do
            n = n + 1
            read( line, *, iostat=ios ) buf( 1 : n )  ! use list-directed input
            if ( ios == 0 ) then
                words( 1 : n ) = buf( 1 : n )   ! if success, copy to the original array
            else
                n = n - 1
                exit       ! if all the words are obtained, finish
            endif
        enddo
    end
    

    Result:

     i=            1 word= hi
     i=            2 word= how
     i=            3 word= are
     i=            4 word= you
     i=            5 word= today
    

    [*] Here is one possible approach for such getnextword(), which obtains a word from an input string (line) via list-directed input and remove that word from the string for next call. If no more word is found in line, found becomes false. (Please search "list-directed input" on the net or in SO pages for more details.)

    program main
        implicit none
        character(100) line, word
        logical found
    
        line = "hi how are you today"
        do
            call getnextword( line, word, found )
            if ( .not. found ) exit
            print "(a,a7,2a)", "word= ", trim( word ), " : line= ", trim( line )
        enddo
    end program
    
    subroutine getnextword( line, word, found )
        implicit none
        character(*), intent(inout) :: line
        character(*), intent(out)   :: word
        logical,      intent(out)   :: found
        integer :: ios
        character(100) :: buf
    
        read( line, *, iostat=ios ) buf   ! try to read one word into a buffer via list-directed input
    
        if ( ios == 0 ) then       ! if success
            found = .true.
            word = trim( buf )      ! save the word
            line = adjustL( line )
            line = line( len_trim( word ) + 1 : )   ! and remove the word from the input line
        else
            found = .false.
            word = ""
        endif
    end
    

    Result:

    word=      hi : line=  how are you today
    word=     how : line=  are you today
    word=     are : line=  you today
    word=     you : line=  today
    word=   today : line=