2017-08-10 108 views
0

我從輸入文件中讀取3個數組(X_halo,Y_halo,Z_halo)。如果我寫入DO循環中加載的值,我可以正確地打印它們,但是不會出現循環。如果我嘗試打印X_halo(i)的值,則會打印不正確的值。爲什麼在Fortran循環之外打印的值不正確?

我該怎麼辦?

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作爲自由變量來使用程序中的所有文件,我該怎麼做?

+0

請將您的標題寫成真正簡短的問題。並且不要添加標籤。請參閱[問]和https://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles –

+0

如果您有兩個問題,請考慮提出兩個單獨的問題。 (我還沒有讀你當前的問題。) –

+0

另外,你添加[tag:fortran90]標籤到你的問題。你確定你想限制自己這個非常舊的版本嗎?有Fortran 95,2003,2008和2015.Fortran 90真的很老,你需要堅持嗎?如果不是,只使用[tag:fortran]。 –

回答

2

不確定爲什麼你會收到一個錯誤,由於istat或爲什麼你的值打印不正確 - 他們對我來說很好,將需要一個最小的完整的可驗證的例子與錯誤消息獲得有關的反饋。

至於讀書少行比ARRAYLEN,如在你前面的問題的意見討論並在上面的評論概括,要檢查是否istat < 0然後從迴路斷線,與

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 

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 

運行此與文件xyz.dat另一種方法是READ通過文件時不保存輸出只是爲了讓行i的數量,然後ALLOCATE你的載體,REWINDREAD在每一行。請參閱How to read number of lines in Fortran 90 from a text file?

+0

謝謝@Steve。我在'y = i-1'和'ALLOCATE(X_halo(y))''X_halo = X_tmp(1:y)'做了一些改動,所以我可以做 'DO i = 1,y PRINT *,X_halo (i) ENDDO' 要列打印。 –

+0

如果你選擇「read to count lines,rewind,read to save data」的方法,你不需要'ARRAYLEN'用於最大行數(無條件的'DO'循環)或'temp'向量。 – Steve

相關問題