簡體   English   中英

如何正確地將 C 字符串讀入未指定長度的 Fortran 字符串?

[英]How to correctly read a C-string into a Fortran string of unspecified length?

以下 function 應該將 C 字符串轉換為 Fortran 字符串,並且在 Release 版本中工作正常,但在 Debug 中不行:

! Helper function to generate a Fortran string from a C char pointer
function get_string(c_pointer) result(f_string)
    use, intrinsic :: iso_c_binding
    implicit none
    type(c_ptr), intent(in)         :: c_pointer
    character(len=:), allocatable   :: f_string

    integer(c_size_t)               :: l_str
    character(len=:), pointer       :: f_ptr

    interface
        function c_strlen(str_ptr) bind ( C, name = "strlen" ) result(len)
        use, intrinsic :: iso_c_binding
            type(c_ptr), value      :: str_ptr
            integer(kind=c_size_t)  :: len
        end function c_strlen
    end interface

    l_str = c_strlen(c_pointer)
    call c_f_pointer(c_pointer, f_ptr)

    f_string = f_ptr(1:l_str)
end function get_string

但是,似乎c_f_pointer沒有告訴 Fortran 指向字符串的指針f_ptr它指向的字符串的長度。 在調試版本中,邊界檢查處於活動狀態,這會導致

Fortran runtime error: Substring out of bounds: upper bound (35) of 'f_ptr' exceeds string length (0)

我正在使用gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0並將標准設置為 2008。

我的問題:有沒有辦法在不更改聲明的情況下告訴f_ptr它的長度,或者我在這里做的事情從根本上是錯誤的?


如果我指定形狀,它似乎可以正確運行,但為此f_ptr需要是一個數組:

character(len=:), allocatable   :: f_string
character(len=1), dimension(:), pointer :: f_ptr
...
call c_f_pointer(c_pointer, f_ptr, [l_str])

但是,我找不到將等級 1 的字符串轉換為character(len=:), allocatable:: f_string的方法,它顯然具有等級 0。

我的第二個問題:在這個例子中有什么方法可以將f_ptr數據傳輸到f_string中嗎?

不能使用c_f_pointer設置Fortran字符指針的長度(F2018,18.2.3.3):

FPTR 應為指針,不應具有延遲類型參數 [...]

因此不能使用延遲長度字符標量(或數組)(長度是類型參數)。

您確實可以使用延遲形狀的字符數組作為fptr ,然后使用任意數量的技術將該數組的元素復制到標量(如前所述,它是 rank-0)。

例如,使用 substring 賦值(在顯式分配延遲長度標量之后):

allocate (character(l_str) :: f_string)
do i=1,l_str
  f_string(i:i)=fptr(i)
end

或者考慮是否可以簡單地使用字符數組而不是復制到標量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM