2016-08-24 25 views
0

我有30個物種的參數值的數據集,我想運行一個腳本來對每個物種進行模擬。參數值當前存儲在.txt文件中,其中每行是不同的物種,每列是不同的參數值。我想要做的是建立一個do循環,讀入每個物種的參數值的相關行,運行仿真腳本,併爲每個物種寫出輸出的.txt文件。不幸的是,我是fortran的新手,並且很難理解如何在do循環的每個步驟中從.txt文件中讀取連續行。我試圖使一個簡單的腳本來測試讀出步驟是否工作:如何讀取fortran中do循環的每個步驟中的文本文件的連續行?

PROGRAM DRIVER 
    IMPLICIT NONE 

    INTEGER :: mm ! I forgot this line in the first version of this question 
    and edited to add it in 
    CHARACTER(7) :: species !! the first column is the species name 
    REAL*8 :: leaf_variable ! The next 3 columns are variable values 
    REAL*8 :: stem_variable ! 
    REAL*8 :: root_variable ! 

    OPEN (12, file = "species_parameters.txt") ! open the .txt file 

    DO mm = 1,30 ! set up the do loop 
     READ (12,*) species, leaf_variable, stem_variable, root_variable 
     ! Read in the species-specific parameter values 
     WRITE (*,*) species, leaf_variable, stem_variable, root_variable 
     ! Print the values on the screen just to show the do loop runs 
    ENDDO 
    END PROGRAM DRIVER 

但是,當我去編譯,我得到的錯誤: 在文件XX(單位= 12,文件=「species_parameters的XX線.txt') Fortran運行時錯誤:文件結尾

我對此文件中的打開和讀取有什麼誤解?

非常感謝您的幫助。

編輯:我想我已經縮小了我的問題。我的理解是在時間的read()發生在一個行中的.txt文件,所以,在這個例子:

read(7, *) species, leaf_variable, stem_variable, root_variable 
    read(7, *) species, leaf_variable, stem_variable, root_variable 

的變量應該.txt文件的第二行中具有相同的值。相反,無論我放入read()函數多少次,變量值都等於第一行。

read(7, *) species, leaf_variable, stem_variable, root_variable, 
      fake_variable1, fake_variable2, fake_variable3, fake_variable4 

其中fake_variable值等於.txt文件的第二行中的值:而且,即使只有4列,我可以,因爲我想用一個read()函數定義爲很多變數。我對read()做了些什麼感到困惑,還是有什麼我需要做的,以防止我的腳本讀取整個.txt文件爲一行?

編輯#2:do循環現在正確地讀取行,現在我已經使用TextWrangler以Unix編碼保存了我的.txt文件。原始文件與Excel一起保存爲.txt文件。這似乎解決了它,但如果任何人有更好的方式來指定輸入文件格式的建議,我會很感激。輸入文件的前幾行是這樣的:當你有一個可執行文件,執行它

species1,1.2,6.54,10.9 
    species2,1.42,3.5,8.23 
    species3,0.85,2.41,4.9 
+1

我沒有看到mm的類型聲明 - do循環的索引變量。考慮從輸入文件中顯示幾行。假設缺少類型聲明是一個轉錄問題 - 一個常見問題是open語句在與文件實際位置不同的目錄中打開一個新的空文件。確保你沒有在其他意想不到的地方創建一個名爲'species_parameters.txt'的文件,在你的open語句中添加一個STATUS ='OLD'說明符(它需要該文件已經存在),然後重試。 – IanH

+1

我不明白 - 你說你在編譯時遇到運行時錯誤?在實際上不應該編譯的代碼上。 – talonmies

+0

對不起,我的錯誤 - mm的變量聲明是我的腳本的第一行,我不知何故將它排除在外。我編輯了我的問題來添加它。因此,我的代碼編譯,並且當我嘗試STATUS ='OLD'時,仍然出現相同的運行時錯誤。 – UCLAEeb

回答

2

運行時錯誤是,它崩潰。編譯時錯誤是編譯器無法生成可執行文件的錯誤。

此代碼不應編譯,因爲您有IMPLICIT NONE,但尚未聲明整數mm

什麼我建議是獲得更多的信息:

program driver 
    use iso_fortran_env 
    implicit none 
    character(len=7) :: species 
    real(kind=real64) :: leaf_variable, stem_variable, root_variable 
    integer :: u, ioerr 
    character(len=120) :: iomsg 

    open(newunit=u, file='species_parameters.txt', action='read', status='old', iostat=ioerr, iomsg=iomsg) 
    if (ioerr /= 0) then 
     print *, "Error opening file" 
     print *, trim(iomsg) 
     stop 1 
    end if 
    do 
     read(u, *, iostat=ioerr, iomsg=iomsg) species, leaf_variable, stem_variable, root_variable 
     if (ioerr /= 0) exit ! exits the loop 
     write(*, *) species, leaf_variable, stem_variable, root_variable 
    end do 
    print *, trim(iomsg) 
    close(u) 
end program driver 

這將始終打印「讀取文件結束」的錯誤,但是這僅僅是檢查程序反正怎麼讀。

這應該編譯,當你運行它時,它應該給你一些錯誤信息。

+1

對於像這樣的測試程序,獲取更多信息的最佳方法是簡單地將輸入/輸出語句等iostat忽略掉。如果出現錯誤情況,Fortran處理器通常會提供相當豐富的消息,作爲錯誤終止的一部分。看看你的例子中read語句的邏輯 - 如果在讀取過程中出現錯誤情況,你所有的程序都會悄悄退出,並且用戶不會有任何線索發生錯誤。如果你打算提供IOSTAT,那麼也提供(並在iostat> 0時報告)IOMSG。 – IanH

+0

感謝您的建議!我忘了在我的問題中包含聲明mm的代碼行,所以我編輯它來添加它。編譯代碼,並打印第一行變量值,而不返回錯誤條件。但是當我試圖在所有的行上運行它(do mm = 1,22)時,沒有打印任何內容,並且它寫了一個名爲fort.1的空文件....你知道這意味着什麼嗎? – UCLAEeb

+0

對不起,應該是(do mm = 1,30) – UCLAEeb

相關問題