为什么在Fortran循环外打印不正确的值?

时间:2017-08-10 18:11:06

标签: fortran

我从输入文件中读取了3个数组(X_haloY_haloZ_halo)。如果我写入在DO循环中加载的值,我可以正确打印它们,但是不在循环中。如果我尝试打印X_halo(i)的值,则会打印不正确的值。

我该怎么做?

program columns
  IMPLICIT NONE

  INTEGER,SAVE :: lun
  INTEGER, PARAMETER :: ARRAYLEN=1044  
  CHARACTER(120) :: filename
  DOUBLE PRECISION, DIMENSION (ARRAYLEN) :: X_halo, Y_halo, Z_halo
  INTEGER :: i, istat

  lun=1
  filename = 'xyz.dat'

  OPEN (UNIT=10, FILE=filename, STATUS='old', ACTION='read', IOSTAT=istat)

    DO i=1,ARRAYLEN
     READ (10, *, iostat=istat) X_halo(i), Y_halo(i), Z_halo(i)
!    print*, 'id:', i, 'X= ', X_halo(i), 'Y= ', Y_halo(i), 'Z= ', Z_halo(i)
    END DO

  DO i=1,ARRAYLEN
  print*, X_halo(i)
  END DO

  CLOSE (10)

end program columns

例如,文件xyz.dat的第一列的第一行是:

 281.0788
 189.8768
 669.2193
 720.7653

但代码返回:

6.9532597489392050E-310
2.2310395176993305E-314
6.9532121310250636E-310
6.9532238136146167E-310

第二个问题:如果你想让ARRAYLEN作为自由变量来使用程序来处理put中的所有文件,我该怎么办呢?

1 个答案:

答案 0 :(得分:2)

不确定为什么因为istat而收到错误或为什么您的值无法正确打印 - 它们对我来说很好,需要一个最小的完整可验证示例,并带有错误消息以获得反馈这一点。

关于阅读比ARRAYLEN更少的行,正如您在上一个问题的评论中所讨论并在上面的评论中所述,您想要检查istat < 0是否从循环中断,用< / p>

IF ( istat < 0 ) THEN
  EXIT
END IF

X_halo作为读取行的长度的一种方法(我怀疑这是最好的方式)是将条目保存到临时向量,检查读取了多少条目使用iALLOCATE您的halo向量,然后从临时向量中复制。

PROGRAM columns
  IMPLICIT NONE

  INTEGER,SAVE :: lun
  INTEGER, PARAMETER :: ARRAYLEN=1044
  CHARACTER(120) :: filename
  ! Read data into tempory arrays of length up to ARRAYLEN
  DOUBLE PRECISION, DIMENSION (ARRAYLEN) :: X_tmp, Y_tmp, Z_tmp
  ! And these will be where we put the data when we know how many lines
  DOUBLE PRECISION, ALLOCATABLE, DIMENSION (:) :: X_halo, Y_halo, Z_halo
  INTEGER :: i, istat

  lun = 1
  filename = 'xyz.dat'

  OPEN (UNIT=10, FILE=filename, STATUS='old', ACTION='read', IOSTAT=istat)

  DO i=1,ARRAYLEN
    ! Read data in to the temporary vectors
    READ (10, *, IOSTAT=istat) X_tmp(i), Y_tmp(i), Z_tmp(i)
    IF ( istat < 0 ) THEN
      ! Then last READ failed with an EOF
      EXIT
    END IF
  END DO

  ! Last READ returned EOF, so i-1 lines were read
  i = i-1

  ALLOCATE(X_halo(i))
  ALLOCATE(Y_halo(i))
  ALLOCATE(Z_halo(i))
  ! Copy i entries in to the allocated vectors
  X_halo = X_tmp(1:i)
  Y_halo = Y_tmp(1:i)
  Z_halo = Z_tmp(1:i)

  PRINT*, X_halo

  CLOSE (10)

END PROGRAM columns

将文件xyz.dat作为

运行
281.0788 1.3 111
189.8768 2.3 222
669.2193 3.3 333
720.7653 4.3 444

返回

   281.07880000000000        189.87680000000000        669.21929999999998        720.76530000000002 

另一种方法是READ通过文件不保存输出只是为了得到行数i,然后是ALLOCATE你的向量,REWIND和{{每行1}}。见How to read number of lines in Fortran 90 from a text file?