将不同长度的字符串传递给Fortran

时间:2018-02-15 21:13:54

标签: string fortran string-formatting fortran90 subdirectory

我正在使用Fortran 90和gfortran编译器作为cygwin的一部分。 我想编写一个函数,它将在一个目录中创建一系列新文件夹,该目录也作为参数传递,并且数字是新连续编号文件夹的最大数量。由于我必须声明字符的长度(即字符串),但也希望普遍能够传递不同的路径,我试图将修剪后的字符串传递给函数。

program main

    implicit none
    character(len = 6) :: newdir
    character(len = 27) :: path
    newdir = "neu1A"
    path = "c:/users/i/desktop/rainer"
    print*,len_trim(path)                 !Outputs the correct length of 25
    print*,len_trim(newdir)               !Outputs the correct length of 5
    call newdirec(trim(newdir),trim(path),5)
end program main

但是由于我必须在函数中重新声明参数,因此在过程中它们的长度会被覆盖/丢失。如何使用正确长度的琴弦并保持功能可用?我必须使用长度,因为构建调用系统创建目录的字符串所需的格式化字符串。我使用的是Fortran 90,因此没有一些选项。

function newdirec(newdir,path, foldnum)

    character (len = 27) :: path
    character (len = 50) :: newdir
    character (len = (len_trim(path) + len_trim(newdir))) :: newpath

    character (len = 100) :: format_string, newdir_len_str, makedir
    integer :: foldnum

    newpath = trim(path)//"/"//trim(newdir)
    print*,len_trim(newpath)      !Outputs the 'wrong' but declared length of 77
    write(newdir_len_str, "(I2)") len_trim(newpath)


    do i = 1, foldnum
        if (i < 10) then
            format_string = "(A"//trim(newdir_len_str)//",I1)"
        elseif (i < 100) then
            format_string = "(A"//trim(newdir_len_str)//",I2)"
        else
            format_string = "(A"//trim(newdir_len_str)//",I3)"
        endif
        write (makedir, format_string) "mkdir "//trim(newpath),i
        !call system(trim(makedir))
        print *, trim(makedir)
    end do
    return 
end function newdirec

2 个答案:

答案 0 :(得分:3)

正如弗拉基米尔所建议的那样,声明子程序或函数的字符参数的正常方法是:

 function newdirec(newdir,path, foldnum)
    character (*) :: newdir,path
    ...

在这种情况下,内部函数LEN允许您获取从调用过程继承的字符串的大小。

我认为没有充分的理由以27或50这样的固定长度声明它们......除非你在不久的将来真的寻找麻烦,例如当你改变调用过程中的声明时:一个长度不匹配通常会导致难以理解的奇怪致命错误。

答案 1 :(得分:2)

感谢Vladimir,Albert和Francois,我按照建议解决了我的问题:

subroutine newdirect(newdir, path, foldnum)

    character(*) :: path, newdir
    character (len = 1024) :: newpath, format_string, newdir_len_str, makedir
    integer :: foldnum

    newpath = trim(path) // "/" // trim(newdir)
    write(newdir_len_str, "(I3.3)") len_trim(newpath) + 6 ! +6 because of "mkdir "
    do i = 1, foldnum
        format_string = "(A" // trim(newdir_len_str) // ",I3.3)" !I3.3: Format for three-digit
        write (makedir, format_string) "mkdir " // trim(newpath), i
        call system(trim(makedir))
        print *, trim(makedir)
    end do
    return
end subroutine newdirect