问题
I am using Fortran 90 with the gfortran compiler as part of cygwin. I want to write a function that will create a series of new folders into a directory that is also passed as a parameter along with a number that is the maximum number of new consecutively numbered folders. Since I have to declare the length of the characters (ie strings) but also want to universally be able to pass different paths, I tried to pass the trimmed strings to the function.
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
But since I have to newly declare the parameters in the function, their length is overwritten/lost in the process. How can I use the correct length of the strings and keep the functional usable universally? I have to use the lengths because of the formatting string needed for building a string that calls onto the system to create the directories. I use Fortran 90, so a few options are not available.
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
回答1:
As Vladimir suggested, the normal way to declare character arguments of a subroutine or function is :
function newdirec(newdir,path, foldnum)
character (*) :: newdir,path
...
In that case, the intrinsic function LEN allows you to get the size of the strings inherited from the calling procedure.
I see absolutely no good reason to declare them with a fixed length like 27 or 50 ... except if you really look for troubles in a near future, for instance when you will change the declarations in the calling procedure : a length mismatch generally leads to a weird fatal error difficult to understand.
回答2:
Thanks to Vladimir, Albert and Francois I sorted out my problem as recommended:
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
来源:https://stackoverflow.com/questions/48816383/passing-character-strings-of-different-lengths-to-functions-in-fortran