首页 > 解决方案 > 一种简单的方法,如何在 Fortran 中格式化输出

问题描述

对于一个较旧的 Fortran 项目,我尝试创建一个现代记录器。它是面向对象编写的,非常类似于 python 的日志库。

困扰我的最后一件事是格式化,我将解释。

我的记录器看起来与这个库非常相似,但是,它不符合我的要求,所以我自己编写了一个。基本上我的日志库看起来像这样:

lg = Logger("super logger")
... other settings ...
lg%log("DEBUG", "A cool message to log", rank)

但是有了这个记录器,我失去了 write 语句的所有格式化功能。基本上在代码中字符串格式化是通过写语句完成的,例如:

write (stdout, '(7X,A,f12.6)') "The great number is ", number

所以现在我必须为每个输出语句和辅助变量有两行代码:

write (message, '(A,f12.6)') "The great number is ", number
lg%log("DEBUG", message, rank)

这不是很方便也不是很好。

我试图做一个格式化函数,但我想这是不可能的参数数量可变(如在 C 中),例如:

function fm(fmt, ...) result(message)

我相信我也无法使用 C 解决方法,因为当我指定绑定接口时,我必须指定参数。

我现在唯一的解决方案(除了两行示例)是为不同的变量重载一些方法并在 c++ 中创建类似流的东西。

我的问题是你有更好的主意吗?理想情况下,如果您知道如何在一行中格式化字符串的选项。

标签: fortranformat

解决方案


您可以将转换为字符串包装在一个函数中,例如

module io
  
  interface str
    module procedure str_real
  end interface
  
contains
  
  function str_real(input,format) result(output)
    real(dp), intent(in) :: input
    character(*), intent(in) :: format
    character(:), allocatable :: output
    
    ! It's probably possible to do the allocation and re-allocation more cleanly.
    allocate(output(100))
    write(output, format) input
    output = trim(output)
  end function
  
end module

然后您可以将其与您的记录器一起使用

lg%log("DEBUG", "The great number is "//str(number,'(f12.6)'), rank)

对于要使用的每种类型,您都需要单独str的函数。


推荐阅读