2011-12-15 90 views
0

我想從輸入文件讀取座標。一個例子輸入文件看起來是這樣的:Fortran讀取動態數組的輸入

1 0.1542 0.2541 1.2451 N 
12 4.5123 2.0014 2.0154 O 
43 8.2145 0.2978 4.2165 H 

等..這個文件的大小是可變的。第一列是分配給原子的數字,以下列是它的x,y,z座標,最後一列是原子的元素符號。

我試圖沿着線的東西:

integer, allocatable :: atnum(:) 
double precision, allocatable :: coord(:,:) 
character(len=2), allocatable :: element(:) 

open(unit=20, file='input', status='old',action='read') 

read(20,*,end=200) atnum, coord(:,1:3), element 
200 close(20) 

這引發了我的錯誤:

Fortran runtime error: Bad integer for item 2 in list input 

我認爲程序讀取第一個進入atnum(1),但隨後試圖繼續閱讀進入第一行的第二項入atnum(2)。我怎樣才能讓它正確讀取輸入?

我也認爲說告訴程序讀中間三列到coord(:,1:3)可能有問題。它很可能會將前三個條目讀入coord(1,1), coord(2,1), coord(3,1),然後碰到該行末尾的字符,並再次感到困惑。我怎麼能告訴它修復該行的第一個下標,並讀入其他維度?或者我將不得不交換指數,如coord(1:3,:)?這會工作嗎?

編輯:上面已經回答了tpg2114,但我仍然有問題。在知道要讀取多少組座標之前,我無法分配數組,但我只知道有多少個原子存在,直到達到文件末尾。如果我沒有分配atnum, coord and element,程序編譯得很好,但是當我嘗試運行時會返回分段錯誤。我怎樣才能讓它讀入動態數組而無需事先分配它們?

這聽起來類似這樣的問題:Variable size arrays in Fortran without Allocate()

在此先感謝。

回答

3

您需要遍歷READ語句。一次讀取只會到記錄的末尾,在這種情況下是行。你會知道什麼時候你用完了,因爲你把end = 200的參數用完了,所以它會跳到第200行(你在這裏似乎沒有)。

所以,你需要確保:

A)你的陣列足夠長,包含文件(你不顯示他們的分配,我假設你分配它們)

B' )循環讀取語句

C)您可以爲atnum參數指定一個索引,並指定coord和elem參數的第一個參數。

例如,假設該聲明是相同的,並且陣列被分配足夠大,且i爲整數

I = 1 
DO 
    read(20,*,end=200) atnum(I), coord(I,1:3), elem(I) 
    I = I + 1 
END DO 
200 continue 

此外,考慮刪除結束= 200部,並使用IOSTAT替代,因爲它是現代並且行號被棄用。

+0

謝謝您的回答。我不知道如何實現讀取數據`do`循環。你是說,而不是`end = 200`我應該有`k = iostat`之類的東西,並且有一個像'do while(k.ge。0)... end do`這樣的循環。那會工作嗎? – 2011-12-15 23:36:33

+0

請閱讀http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/iostatus.html,瞭解有關IOSTAT如何工作的說明。 – tpg2114 2011-12-15 23:45:56

2

步驟1:讀取文件,將每行讀入一個字符串,僅將行數爲「num_lines」,使用「iostat」檢測文件結束條件。

第2步:倒帶文件。

第3步:將數組分配到正確的長度「num_lines」。

第4步:做「實際」的元素文件讀入到數組,元素:

do i=1, num_lines 
    read (20, *) atnum(I), coord(I,1:3), elem(I) 
end do