2013-10-17 133 views
4

我做了一些虛擬代碼來學習打開和讀取文件。比方說,TEST.DAT讀取在fortran中打開並讀取一行數據90

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

我寫了下面的代碼來打開和讀取

subroutine readdata 
implicit none 

integer    :: j 
double precision :: test 

open(unit = 100, file = 'test.dat', status = 'old', action = 'read') 
do j = 1, 10 
read(100,*) test 
print *, 'N1=', test 
end do 

end subroutine 

輸出如下所示的數據文件,我有以下的,符合市場預期

gfortran -g -I/usr/include -o main main.o subroutines.o -L/usr/lib64/liblapack -L/usr/lib64/libblas 
test= 1.0000000000000000  
test= 2.0000000000000000  
test= 3.0000000000000000  
test= 4.0000000000000000  
test= 5.0000000000000000  
test= 6.0000000000000000  
test= 7.0000000000000000  
test= 8.0000000000000000  
test= 9.0000000000000000  
test= 10.000000000000000  
Main finished. 

但是,如果數據按如下方式存儲在單行中:

1 2 3 4 5 6 7 8 9 10 

那麼上面的代碼不能按需要工作。它只讀取該行中的第一個元素,然後提示錯誤

[email protected]:~/PHD_research/myCodes/data> ./runcase.sh 
rm -f *.o *.mod *.MOD *.exe *.stackdump main 
gfortran -g -I/usr/include -c main.f90 
gfortran -g -I/usr/include -c subroutines.f90 
gfortran -g -I/usr/include -o main main.o subroutines.o -L/usr/lib64/liblapack -L/usr/lib64/libblas 
test= 1.0000000000000000  
At line 9 of file subroutines.f90 (unit = 100, file = 'test.dat') 
Fortran runtime error: End of file 

所以,我的問題是,我有一個包含2879(1×2879)存儲在一個單一的行數的數據文件。我將如何打開並讀取數據文件中的所有數字?

回答

11

默認情況下,每個Fortran read語句讀取一個值列表,然後前進到下一行的開頭。將read想象爲在輸入文件中移動光標,因爲它工作正常。因此,您的聲明

read(100,*) test 

當輸入文件中的數字位於不同的行上時,您會做什麼。當它們全部位於文件的同一行時,第一個讀取語句讀取一個值(即test),然後前進到下一行的開頭以讀取下一個值,但沒有下一行,並且運行時錯誤你已經向我們展示了。

有兩個簡單的解決方案。

一,你可以在一個語句從行讀取多個值,例如,你可能聲明

real, dimension(10) :: test 

然後

read(100,*) test 

應該得到一個去所有的值到數組。

其次,您可以使用non-advancing輸入,它告訴處理器在每個read語句後不跳到下一行的開頭。類似下面的(檢查編輯描述符的情況下)

read(100,'(f8.2)',advance='no') test 

如果選擇後一種方法,不要忘了,你已經從線讀取所有的值之後,你想跳到開始的下一行,所以你可能需要執行一個語句,如

read(100,*) 

它不讀取任何值,但前進到下一行。

+0

請注意,非前進輸入需要明確的格式。 – IanH

+0

謝謝@IanH,我編輯了我的答案。 –

0

正如所指出的前,可以連續讀取數據加入

advance='no' 

和適當的格式字符串(取決於您的數據,例如「I2」的工作就像一個數據表[1 2 3 4 5 6])到您的閱讀命令。 另一個有用的技巧是通過將參數的值寫入參數(即io)並退出do循環而不會出現運行時錯誤,從而額外處理I/O狀態,即使您不知道數據表的長度。一個完整的程序可能例如如下所示:

program read 
integer::a,io 

open(100, file='data') 
do 
read(100,'(i2)',advance='no',IOSTAT=io)a 
if (io<0) exit 
if (io>0) stop 'problem reading' 
write(*,*)a 
end do 

end program 

玩得開心!