1

我是 Fortran 的新手,我需要编写一个代码,允许我读取一个文本文件(.dat),其中包含不规则空格/不规则分隔的数据数组(1876 列 x 3126 行)并将其写入新文件具有一致的格式。简而言之,我希望数据的列相互对齐。

前任:

 <4 spaces>    0.2341   15.0769
 <2 spaces>  -10.0672    1.6278    
 <3 spaces>   66.9851  -14.7123
 <3 spaces>   -0.4468   -2.5673

上面的示例基本上是数据列应该是什么样子,每个值之前都有相应的空格数,如图所示。值的格式为“f10.4”

这是我尝试编写的代码。我能够编译代码并运行 exe 文件,但是,它无法从文本文件中读取并产生运行时错误:文件结束。

program refgrid
implicit none

   integer :: nrow, ncol
   integer :: i, j
   real, dimension(:,:), allocatable :: mat

   print *, ' Input number of rows: '
   read *, nrow
   print *, 'Input number of columns: '
   read *, ncol

   allocate(mat(1:ncol,1:nrow))

   open(UNIT=1, FILE='bathymetry2.dat', FORM='FORMATTED', STATUS='OLD', ACTION='READ')

   do i=1, nrow
      read(UNIT=1, FMT=*) mat
   end do

   close(UNIT=1)

   open(UNIT=1, FILE='refgrid.dat', FORM='FORMATTED', STATUS='NEW', ACTION='WRITE')

   do i=1, nrow
      write(UNIT=1, FMT=101) mat
      101 format(1826f10.4)
   enddo

   close(UNIT=1)

end program refgrid

我的问题:

  1. 如何使用 do 循环从一行中连续读取值?在“do”循环中使用 f 格式的重复功能时,我有点困惑。

  2. 我可以将数组“mat”作为一个整体读/写吗?或如何分配 data_list 进行读/写?我可以分配整个矩阵而不是单个元素吗?

对于此事,我将不胜感激。谢谢!

4

1 回答 1

1

问题是,在 do 循环中的每次迭代中,您都会尝试读取与整个数组一样多的元素mat。您应该在每次迭代中只填写一列。或者,您可以使用一条读取语句读取整个数组,而无需任何循环。

至于写作,您需要重复格式与列数一样多。我建议动态创建一个格式字符串,以便它自动适应用户输入的列数。请参见下面的示例。您也可以省略用于写入的 do 循环,因为 Fortran 会在所有格式规范都已使用时自动添加记录结束符号(换行符),并且它将再次开始应用它们。

program refgrid
  implicit none

  integer :: nrow, ncol
  real, allocatable :: mat(:,:)
  character(20) :: form

  print *, ' Input number of rows: '
  read *, nrow
  print *, 'Input number of columns: '
  read *, ncol

  allocate(mat(1:ncol, 1:nrow))
  open(unit=1, file='bathymetry2.dat', status='OLD', action='READ')
  read(1, *) mat
  close(1)

  write(form, "(A,I0,A)") "(", ncol, "F10.4)"
  open(1, file='refgrid.dat', form='FORMATTED', status='NEW', action='WRITE')
  write(1, form) mat
  close(1)

end program refgrid

更新:至于格式说明符的动态创建:您在字符串中写入form三件事:一个字符串 ( A)、一个仅包含所需字符数的整数 ( I0) 和另一个字符串 ( A)。第一个字符串是(,整数是ncol,第二个字符串是F10.4)。所以,只要ncol有 value 128,你就会有formstring (128F10.4)。这是一个包含有效格式说明符的字符串,因此您可以在 write 语句中使用它而不是硬编码格式说明符。

于 2013-03-21T17:13:44.343 回答