Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

fortran90 - Assumed string length input into a Fortran function

I am writing the following simple routine:

program scratch
    character*4 :: word
    word = 'hell'
    print *, concat(word)
end program scratch

function concat(x)
    character*(*) x
    concat = x // 'plus stuff'
end function concat

The program should be taking the string 'hell' and concatenating to it the string 'plus stuff'. I would like the function to be able to take in any length string (I am planning to use the word 'heaven' as well) and concatenate to it the string 'plus stuff'.

Currently, when I run this on Visual Studio 2012 I get the following error:

Error 1 error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands. D:aboufiraDesktopTEMPVisual Studioestlogicalfunctionscratch.f90 9

This error is for the following line:

concat = x // 'plus stuff'

It is not apparent to me why the two operands are not compatible. I have set them both to be strings. Why will they not concatenate?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

High Performance Mark's comment tells you about why the compiler complains: implicit typing.

The result of the function concat is implicitly typed because you haven't declared its type otherwise. Although x // 'plus stuff' is the correct way to concatenate character variables, you're attempting to assign that new character object to a (implictly) real function result.

Which leads to the question: "just how do I declare the function result to be a character?". Answer: much as you would any other character variable:

character(len=length) concat

[note that I use character(len=...) rather than character*.... I'll come on to exactly why later, but I'll also point out that the form character*4 is obsolete according to current Fortran, and may eventually be deleted entirely.]

The tricky part is: what is the length it should be declared as?

When declaring the length of a character function result which we don't know ahead of time there are two1 approaches:

  • an automatic character object;
  • a deferred length character object.

In the case of this function, we know that the length of the result is 10 longer than the input. We can declare

character(len=LEN(x)+10) concat

To do this we cannot use the form character*(LEN(x)+10).

In a more general case, deferred length:

character(len=:), allocatable :: concat  ! Deferred length, will be defined on allocation

where later

concat = x//'plus stuff'  ! Using automatic allocation on intrinsic assignment

Using these forms adds the requirement that the function concat has an explicit interface in the main program. You'll find much about that in other questions and resources. Providing an explicit interface will also remove the problem that, in the main program, concat also implicitly has a real result.

To stress:

program
  implicit none
  character(len=[something]) concat
  print *, concat('hell')
end program

will not work for concat having result of the "length unknown at compile time" forms. Ideally the function will be an internal one, or one accessed from a module.


1 There is a third: assumed length function result. Anyone who wants to know about this could read this separate question. Everyone else should pretend this doesn't exist. Just like the writers of the Fortran standard.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...