Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

character string functions

forall
Beginner
372 Views
I am trying to create a compact function for replacing the if block

if(present(optvar))then
var=optvar
else
var=defvar
endif

since it crops up a lot in my codes and I like the more compact form var=myIf(optvar,defvar).

I have overloaded real,integer and logical definitions of var, but having difficulties with the character version, due to Fortran-language constraints in specification expressions.

The following is the best I can come up with, but its still not quite right since it will result in wrong results ("character loss") if len(tsource)>len_If_ch2. If I make len_myIf_ch2 extremely large then it becomes very wasteful, since usual arguments will be 4-5 character strings (but occasionally long file paths as well!).

!---------------------------------------
elemental function myIf_ch2(tsource,fsource)
implicit none
character(*),optional,intent(in)::tsource
character(*),intent(in)::fsource
integer(mik),parameter::len_myIf_ch2=100
character(len=max(len(fsource),len_myIf_ch2))::myIf_ch2
if(present(tsource))then
myIf_ch2=tsource
else
myIf_ch2=fsource
endif
! End procedure here
endfunction myIf_ch2
!---------------------------------------

is it possible to write such a routine in a more robust way? thanks in advance!
0 Kudos
2 Replies
ingo_berg
Beginner
372 Views
Hi,

you can try the following code. The length of the return string will be the maximum length of both input strings. It works for me

pure function ite_fss(a_bCond, a_iVal1, a_iVal2)

implicit none

logical, intent(in) :: a_bCond
character(LEN=*), intent(in) :: a_sVal1, a_sVal2
character(LEN=max(len_trim(a_sVal1), len_trim(a_sVal2) ) ) :: ite_fss

if (a_bCond) then
ite_fss = a_sVal1
else
ite_fss = a_sVal2
end if

end function
0 Kudos
gregscvf
Beginner
372 Views
I think what you want is Pure Function in the length definition of the character function. You then supply the Pure Function to provide the length needed depending on the variables provided. Something like:
Code:
!Max_Length_Char--Tests Character Function
!Returned length depends on length and presence of inputs
MODULE XYS_Mod
CONTAINS

FUNCTION XYStrings(Str1, Str2)
character*(*), optional, intent(in):: Str1
character*(*), intent(in):: Str2
character(Len = XYS_Len(Str1, Str2)):: XYStrings
	if(present(Str1))then
		XYStrings = Str1
	else
		XYStrings = Str2
	end if
END FUNCTION XYStrings

PURE INTEGER FUNCTION XYS_Len(Str1, Str2)
character*(*), optional, intent(in):: Str1
character*(*), intent(in):: Str2
	if(present(Str1))then
		XYS_Len = Len(Str1)
	else
		XYS_Len = Len(Str2)
	end if
END FUNCTION XYS_Len

END MODULE XYS_Mod

!
Program Max_Length_Char
use XYS_Mod
implicit none
character*(*),parameter:: CH1='This is the first string'
character*(*),parameter:: CH2='This is a much longer second string'
	Write(*,'(A)')'"' // XYStrings(Str2 = CH2) // '"'
	Write(*,'(A)')'"' // XYStrings(CH1, CH2) // '"'
end
Greg
0 Kudos
Reply