首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在Fortran循环之外打印不正确的值?

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

Stack Overflow用户
提问于 2017-08-10 18:11:05
回答 1查看 455关注 0票数 1

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

我该怎么做呢?

代码语言:javascript
复制
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的第一列的第一行是:

代码语言:javascript
复制
 281.0788
 189.8768
 669.2193
 720.7653

但是代码返回:

代码语言:javascript
复制
6.9532597489392050E-310
2.2310395176993305E-314
6.9532121310250636E-310
6.9532238136146167E-310

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-10 23:30:13

不确定您为什么会因为istat而收到错误,或者为什么您的值没有正确地打印--它们对我来说很好,需要一个包含错误信息的最小的完整可验证的示例来获得反馈。

关于读取比ARRAYLEN更少的行,正如您在上一个问题中的注释中讨论并在上面的注释中所概述的那样,您希望检查istat < 0是否会中断循环,使用

代码语言:javascript
复制
IF ( istat < 0 ) THEN
  EXIT
END IF

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

代码语言:javascript
复制
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作为

代码语言:javascript
复制
281.0788 1.3 111
189.8768 2.3 222
669.2193 3.3 333
720.7653 4.3 444

返回

代码语言:javascript
复制
   281.07880000000000        189.87680000000000        669.21929999999998        720.76530000000002 

另一种方法是通过文件进行READ,而不是为了获得i的行数而保存输出,然后在每一行中ALLOCATE您的向量、REWINDREAD。请参阅How to read number of lines in Fortran 90 from a text file?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45620759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档