Fortran:从文本文件读取和打印2D数组

问题描述 投票:0回答:1

我是fortran 90的新手,我要做的就是读取一个3x3数组并将其打印出来,但是我遇到了行尾错误:

文本文件包含以下数组:

1 2 3

4 5 6

7 8 9

这是我的代码:

program myfile
implicit none 

! Declare Variables
integer i,j
!real, dimension(1:3,1:3) :: A
integer, parameter :: M = 3, N =3
real, dimension(1:M,1:N) :: A

! Open and read data
open(unit=10, file = 'test_file_cols.txt', status = 'old')
do i =1,M
    do j =1,N
        read(unit=10,FMT=*) A(i,j)
        print *,A(i,j)
    end do
end do      

end program myfile

我得到的错误如下:

1.000000

4.000000

7.000000

forrtl:严重(24):读取期间文件结尾,单元10,文件C:\ Users \ M42141 \ Documents \ mean_flow_file \ test_file_cols.txt

fortran fortran90
1个回答
0
投票

默认情况下,如注释中简要讨论的那样,Fortran中的所有I / O都是基于记录的。对于格式化和未格式化的文件都是如此。发生的情况是将文件视为一组记录-您可以将一条记录视为文件中的一行。现在这些行可能非常长,尤其是在未格式化的文件中,但是默认的Fortran I / O方法仍将其视为一组行。

现在重要的是,默认情况下,每次执行I / O语句(读,写,打印)时,它所做的最后一件事就是从它所处的记录移至下一条记录-写语句将写一条记录结束标记。这就是为什么在write语句之后自动获取换行符的原因,但是这也意味着对于read语句,记录(在线)上的所有剩余数据都将被跳过。这就是您正在发生的事情。第一次读取将读取记录1,因此您将获得1.0,然后移至记录2。您的程序随后将读取记录2,因此您将获得4.0,然后它自动移至记录3。然后读取(9.0)和文件指针移到记录4上。您然后尝试读取该记录,但没有记录4,因此遇到了文件结尾错误。

记录结构在初次遇到时有点奇怪,但是当您习惯它时,它非常强大且方便-我将在下面显示一个示例,另外一个可能是您可以在最后留下评论在每一行都说明了它的作用的情况下,read语句的结尾将意味着您移至下一条记录,因此跳过注释,并且无需在代码中采取任何特殊操作即可处理这种情况。

无论如何解决案件。三种可能的方式

  1. 一次读取整条记录-注释表明存在隐式的do循环,但我认为在这种情况下,数组部分更容易且更直观
  2. 您可以一次性读取整个数组。之所以可行,是因为当一条read语句完成一条记录并发现它仍然“需要”更多数据时,它将携带到下一条记录中并继续读取。但是请注意,行尾注释的想法在这里不起作用-您能找出原因吗?
  3. 非高级I / O。在这种情况下,我完全不建议这样做,但出于完整性考虑,这使您无需进行下一条记录即可执行读取或写入操作

[可能还有其他人,您可能会使用所谓的流I / O,但就个人而言,我更喜欢基于记录的记录,我发现它更加方便和强大。无论如何,这里是一个说明这三种方法的程序。请注意,我也更改了您的输入文件,使原始文件可以与非高级I / O一起使用很麻烦,但其他2则不行-另一个原因是此处不使用它。

ian @ eris:〜/ work / stack $ cat readit.f90

Program readit

  Implicit None

  Real, Dimension( 1:3, 1:3 ) :: a

  Integer :: i, j

  ! one line per read
  Write( *, * ) 'Line at a time'
  Open( 10, file = 'in' )
  Do i = 1, 3
     Read ( 10, * ) a( i, : )
     Write(  *, * ) a( i, : )
  End Do
  Close( 10 )

  ! All in one go
  Write( *, * ) 'All in one go'
  Open( 10, file = 'in' )
  Read ( 10, * ) a
  Write(  *, * ) a
  Close( 10 )

  ! Non advancing I/O
  Write( *, * ) 'Non-advancing'
  Open( 10, file = 'in' )
  Do i = 1, 3
     Do j = 1, 3
        ! Non advancing I/O requires a 'proper' format
        Read ( 10, '( f3.1, 1x )'    , Advance = 'No' ) a( i, j )
        Write(  *, '( f3.1, 1x )', Advance = 'No' ) a( i, j )
     End Do
     ! Move to next records (lines)
     Read ( 10, * )
     Write(  *, * )
  End Do
  Close( 10 )

End Program readit
ian@eris:~/work/stack$ gfortran-8 -Wall -Wextra -pedantic -std=f2008 -fcheck=all -O readit.f90
ian@eris:~/work/stack$ cat in
1.0 2.0 3.00 
4.0 5.0 6.00 
7.0 8.0 9.00 

ian@eris:~/work/stack$ ./a.out
 Line at a time
   1.00000000       2.00000000       3.00000000    
   4.00000000       5.00000000       6.00000000    
   7.00000000       8.00000000       9.00000000    
 All in one go
   1.00000000       2.00000000       3.00000000       4.00000000       5.00000000       6.00000000       7.00000000       8.00000000       9.00000000    
 Non-advancing
1.0 2.0 3.0 
4.0 5.0 6.0 
7.0 8.0 9.0 
© www.soinside.com 2019 - 2024. All rights reserved.