Strings as Subprogram Arguments

When a subprogram takes a string as an argument, we may want to pass strings of different lengths.

        module constants
            integer, parameter :: MAX_CHROMOSOME_LEN = 1000000, &
                                  MAX_GENE_LEN = 20000, &
                                  MAX_MARKER_LEN = 20
        end module
        program string_subprograms
            implicit none
            character(MAX_CHROMOSOME_LEN) :: chrom1, chrom2
            character(MAX_GENE_LEN) :: eye_gene1, eye_gene2, hair_gene1
            character(MAX_MARKER_LEN) :: start_seq, stop_seq
            integer :: start_offset, code_offset, stop_offset
            ! Find location of sequences within a chromosome
            start_offset = locate(chrom1, start_seq)
            stop_offset = locate(chrom1, stop_seq)
            code_offset = locate(chrom1, gene_seq)
        end program

Unlike other arrays, it is not necessary to pass the maximum length of a string. We simply define dummy string variables with a * for the size, and the compiler takes care of the rest. The compiler will pass the length of the string to the subprogram for us, and we can retrieve it using len(string), where string is the name of the dummy argument.

        subroutine sub(string)
            character(*) :: string
            ! Produces the correct length of the string passed in each time
            print *, len(string)
        end subroutine

The locate function above can then be implemented as follows:

        function locate(big_sequence, sub_sequence)
            integer :: locate
            character(*) :: big_sequence, sub_sequence
            integer :: sub_len
            character :: trimmed_seq
            ! Indicate that sub_sequence was not found
            locate = -1
            ! Set locate to index of first match, if found
            trimmed_seq = trim(sub_sequence)
            sub_len = len(trimmed_seq)
            do i = 1, trim_len(big_sequence)
                if ( big_sequence(i:i+sub_len) == trimmed_seq ) then
                    locate = i
        end function