如何在Fortran中读取可能包含很长行的文本文件

时间:2016-01-12 14:35:52

标签: file-io fortran

假设我的文本文件可能包含很长的文本行,例如

short
short
reeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnggg
short as well
short

我可以编写一个读取此文件的简单程序:

program main
implicit none
integer, parameter        :: BIG_NUMBER = 400
integer                   :: lun
character(len=BIG_NUMBER) :: line
integer                   :: istat

open(newunit = lun, file = 'myfile')

do
   read (lun, '(A)', iostat = istat) line
   if (istat /= 0) exit
end do

end program main

这仅支持文本文件,其中所有行不超过400个字符。在C中,使用指针,类似的程序会自动支持任何文本文件。

如何以可以读取所有长度的行的方式重写示例程序?

2 个答案:

答案 0 :(得分:5)

您可以使用非前进输入将行的连续块读取到缓冲区中,然后将每个块组合在一起以形成延迟长度字符变量中的完整行。例如:

subroutine get_line(lun, line, iostat, iomsg)
  integer, intent(in)           :: lun
  character(len=:), intent(out), allocatable :: line
  integer, intent(out)          :: iostat
  character(*), intent(inout)   :: iomsg

  integer, parameter            :: buffer_len = 80
  character(len=buffer_len)     :: buffer
  integer                       :: size_read

  line = ''
  do
    read ( lun, '(A)',  &
        iostat = iostat,  &
        iomsg = iomsg,  &
        advance = 'no',  &
        size = size_read ) buffer
    if (is_iostat_eor(iostat)) then
      line = line // buffer(:size_read)
      iostat = 0
      exit
    else if (iostat == 0) then
      line = line // buffer
    else
      exit
    end if
  end do
end subroutine get_line

答案 1 :(得分:1)

除非有一些限制,否则永远不要寻找另一种解决方案。既然你可以在C语言中使用C和Fortran之间的所有互操作性东西,我建议你用C编写一小部分程序来处理读数。 C部分可以像一组2个函数和几个全局变量一样简单:

  1. 一个函数,用于查询实际读取下一行的下一行的大小,并将其大小返回到fortran,以及EOF标志
  2. 一个函数,用于获取将行数据返回到fortran的下一行数据。
  3. 例如,如果您使用getline,则全局变量将是File对象,行缓冲区和缓冲区大小。此外,您可以添加另外两个由fortran调用来打开和关闭文件的函数,或者您可以在查询函数中处理所有这些函数。