如何将 C 字符串正确读取为未指定长度的 Fortran 字符串?

2024-01-20

以下函数应该将 C 字符串转换为 Fortran 字符串,并且在发布版本中工作正常,但在调试中不行:

! 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 https://gcc.gnu.org/onlinedocs/gfortran/C_005fF_005fPOINTER.html不告诉 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 应为指针,不应具有延迟类型参数 [...]

因此不能使用延迟长度字符标量(或数组)(长度是类型参数)。

你确实可以使用延迟-shape字符数组为fptr然后使用任何技术数量 https://stackoverflow.com/a/37980844/3157076将该数组的元素复制到标量(如上所述,其等级为 0)。

例如,使用子字符串赋值(在显式分配延迟长度标量之后):

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

或者考虑是否可以简单地使用字符数组而不是复制到标量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 C 字符串正确读取为未指定长度的 Fortran 字符串? 的相关文章

  • 可变格式

    我编写了一个程序来计算平方有限差分矩阵 您可以在其中输入行数 等于列数 gt 这存储在变量矩阵中 该程序运行良好 program fin diff matrix implicit none integer dimension allocat
  • 如何在 conda 中静音或抑制 gfortran (或 clang?)后端?

    我一直致力于构建一个非常特殊的 conda 环境 专为python and R与串扰使用rpy2 我想出的方法可以安装正确的R包如下 install main environment sh now date T echo Start Tim
  • f951 错误:无法识别的命令行选项

    我在linux上 正在编译以下内容 mpif90 shared source F90 object1 o object2 o L some path Qoption link rpath some path I some path lhdf
  • 识别操作系统

    我在 Intel 编译器上的 Fortran 90 代码取决于它运行的操作系统 例如 if OS win7 then do X else if OS linux then do y end if 我如何以编程方式执行此操作 您可以使用预处理
  • Fortran gfortran linux 中的“分段错误(核心转储)”错误

    我正在创建一个程序 该程序将分析目录中的文件 fits 然后它将在另一个目录中创建另一个文件 txt 它只是一个转换器 当我尝试执行该程序 编译正常 时 它给了我一条错误消息 程序收到信号 SIGSEGV 分段错误 无效的内存引用 此错误的
  • GO TO 语句 - Fortran 到 Matlab

    我一直在努力将此网格搜索代码从 Fortran 转换为 Matlab 但是我无法正确合并 GO TO 语句 我正在尝试使用 while 循环 但我认为我需要其他东西来结束搜索 任何帮助将不胜感激 vmax 1 0E 15 amax G 1
  • 这些双精度值如何精确到小数点后 20 位?

    当精度是一个问题时 我正在测试一些非常简单的等价错误 并希望以扩展双精度执行操作 这样我就知道答案在 19位数字中 然后以双精度执行相同的操作 其中第 16 位会有舍入误差 但不知何故 我的双精度算术保持了 19 位精度 当我在扩展双精度中
  • 在 VSCode Fortran 调试中检查从另一个模块导入的变量

    我正在调试一些包含许多 Fortran 模块的代码 其中一些模块彼此共享变量 不幸的是 带有 VScode 的 gdb 在调试时似乎无法检查导入的变量 目前 当我需要检查导入的变量时 唯一的方法是停止调试 并手动更改代码以包含等于导入变量的
  • 使用 Cygwin64 的 Fortran MPI

    我正在使用 Codeblock IDE 编写和编译我的 Fortran 程序 现在我想将 MPI 包含到我的 GNU Fortran 编译器中 在遵循 GNU GCC 编译器的一些指南之后 我突然想到我需要为 MPICH2 设置以下内容 有
  • 带有数字/标签的 Fortran IF 语句而不是另一个语句

    这段 Fortran 代码的含义是什么 IF J1 3 20 20 21 21 J1 J1 3 20 IF J2 3 22 22 23 23 J2 J2 3 22 CONTINUE 我在旧项目中看到过 我不知道这个带有数字 标签 的 IF
  • 使用 Fortran 90 正确读取输入文件中的注释行

    据我了解 Fortran 在从文件读取数据时 会跳过以星号 开头的行 假设它们是注释 好吧 我似乎在用我创建的一个非常简单的程序实现这种行为时遇到了问题 这是我的简单 Fortran 程序 1 program test 2 3 intege
  • 如何从 Fortran 调用 R 函数?

    根据http gallery rcpp org articles r function from c http gallery rcpp org articles r function from c Rcpp 允许用户从 C 调用 R 函数
  • 如何在 Sublime Text 2 的 OSX 终端中显示构建结果

    我刚刚从 TextMate 切换到 Sublime Text 2 我非常喜欢它 让我困扰的一件事是默认的构建结果显示在 ST2 的底部 我的程序产生一些很长的结果 显示它的理想方式 如在 TM2 中 是并排查看它们 如何在 Mac 操作系统
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • 当输入字符而不是数字时,防止 FORTRAN 关闭

    我有一个读取语句需要一个数字 非常简单的示例代码 program test integer var read var end 问题是我通常输入一串字符 即 yes 因为分心 如何防止我的代码完全停止并显示以下类型的错误消息您输入了错误的值
  • 如何在fortran中调用和使用另一个子程序中的子程序?

    我正在编写一个程序 其中主程序包含许多子例程和函数 为了构造主程序的这些子程序之一 假设是子程序 A 我需要使用另一个子程序 假设是 B 我的问题是 如何调用子程序A并使用子程序B 我是初学者 我已经搜索了很多 但没有找到我清楚理解的东西
  • 向具有 TARGET 属性的虚拟参数的过程提供不具有 TARGET 属性的参数

    在 Fortran 语言中 向具有 TARGET 属性的虚拟参数的过程提供不具有 TARGET 属性的参数应该会导致无效代码 但是 当使用 gfortran 5 1 0 或 ifort 14 0 0 编译以下代码时 不会检测到错误 并且程序
  • 如何在 Fortran 中实现数组结构而不是结构数组?

    我正在使用 Fortran 编写有关 CFD 主题的代码 在与一些计算机科学领域的朋友讨论后 他们告诉我 如果在他 她的代码中实现数组结构 SoA 而不是结构数组 AoS 可以加快计算时间 我见过很多关于这个主题的实现的例子 但大多数都是用
  • 使用 OpenMP 并行嵌套循环运行缓慢

    我有一个 fortran 程序的一部分 其中包含一些嵌套循环 我想将其与 OpenMP 并行化 integer nstates N i dima dimb dimc a row b row b col c row row col doubl
  • & 位于第 5 列和行尾

    我今天遇到一些代码 如下所示 subroutine sub hello world this routine takes a crazy large number of arguments so many that it gets spli

随机推荐