在 Fortran 中分配字符数组
Posted
技术标签:
【中文标题】在 Fortran 中分配字符数组【英文标题】:Assigning a character array in Fortran 【发布时间】:2014-03-13 17:55:03 【问题描述】:我必须编写一个可以被 C 和 Fortran 调用的子例程。该子例程将文件名作为其参数之一。我知道要与 C 很好地互操作,ISO C 绑定建议使用字符数组进行互操作。
我的问题是:是否存在易于编写的字符数组字面量之类的东西?我有一个这样的子程序:
subroutine my_sub(char_array)
use iso_c_binding, only: c_char
char(kind=c_char, len=1), dimension(:), intent(in) :: char_array
...
end subroutine my_sub
是否可以通过以下方式调用它:
call my_sub('Hello World!')
或者我必须做一些可怕的事情,比如:
call my_sub((/ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' /))
我的主要问题似乎是它不喜欢假定形状的数组,并且给它一个集合(大)大小也会输出所有后来碰巧被拾取的垃圾内存。
有更好的方法吗?
【问题讨论】:
【参考方案1】:序列关联的规则允许类似的情况。你可以使用
call my_sub('Hello World!')
但前提是你的数组假定大小为dimension(*)
或明确的形状。
通常,在 Fortran 2008 中,您不能将假定形状数组用于 C 互操作过程。这将改变我的未来,但会更加复杂。
还有一个重要的评论。仅使用iso_c_binding
模块不会使过程具有 C 互操作性。 您必须使用bind(C)
,可能带有绑定名称。这才是最重要的。即使没有模块,您也可以创建可互操作的程序(仅限有限的程序)。传递字符串而不是 1 字符数组的特性也取决于此。
这就是为什么我不喜欢说“使用 iso_c_binding 创建可互操作的过程”。
过程的接口必须在 Fortran 中显式。
【讨论】:
对不起,我错过了 bind(C) 和名称(我使用了各种不同的编译器,所以我想确保我得到尽可能一致的命名)。bind(C)
是关键!甚至iso_c_binding
也不那么重要,在这里几乎不需要,它只包含几个常量和过程。
哦,我的意思是在我的代码中 sn-p。我的所有子程序中都有 bind(C) 。 :)
好吧,不幸的是,gfortran
接受了假设的形状数组,尽管这显然是一个问题。使用ifort
我得到error #8520: An array dummy argument of a BIND(C) procedure must be an explicit shape or assumed size array.
现在可能会放松,但我相信无论如何都会发出警告。【参考方案2】:
您可以使用传输功能。这是一个示例代码。
program string0
implicit none
character, allocatable :: string(:)
character(len = :), allocatable :: text
text = 'this is a pen'
string = transfer(text, ' ', size = len_trim(text))
string = achar(iachar(string) - 32)
text = transfer(string, text)
print *, text
stop
end program string0
【讨论】:
以上是关于在 Fortran 中分配字符数组的主要内容,如果未能解决你的问题,请参考以下文章