2011-11-18 43 views
2

我在編輯fortran 90來讀取文件。一個特定的文件碰巧被一些額外的信息「污染」,所以我想嘗試一個閱讀然後倒帶;如果在錯誤重讀:保存文件位置並返回fortran 90

open(filenum,file=filename,form="unformatted",iostat=ierr) //'direct' access 
...lots of stuff... 
here = ftell(filenum) 
read(filenum,iostat=ierr) var1, var2    //try reading as var1, var2 
if(iswrong(var1, var2)) then      //check if correct 
    call fseek(filenum,here-ftell(filenum),1)  //rewind 
    read(filenum,iostat=ierr) vara, varb, varc  //read as different type 
endif 

然而,當我編譯這個程序,我得到

Undefined symbols: 
    "_fseek_", referenced from: 
     ___myreader__subroutine_name in myreader.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

(我試圖編譯的gfortran(i686的 - 蘋果darwin8-gfortran-4.2))。我明白fseek不是標準的fortran程序。

我不知道是否有一種替代方法。我知道我可以做類似read(filenum,rec=somevalue)的東西,但我怎樣才能以類似的方式使用它?我也想過嘗試向read(,advance='no')閱讀測試,然後用advance='yes'再次閱讀,如果它是正確的格式,但是這需要一個特定格式的表達,這是沒有規定。謝謝。

+0

你從哪裏得到ftell和fseek?這聽起來像你真正想要做的IO流,而不是直接IO ... – haraldkl

+0

感謝@haraldkl,我明白了[這裏](http://gcc.gnu.org/onlinedocs/gfortran/FSEEK.html)和其他地方...如果我使用流IO而不是直接讀取語句,會不會改變?這是一個很大的程序,我沒有寫,所以我認爲我很難追捕和修改程序的其餘部分。 – hatmatrix

+0

你忘記了呼叫,在你鏈接到的gfortran的文檔中,它表示它是一個子程序,而不是函數,因此需要呼叫。流IO將略有不同,但可移植到其他編譯器。 – haraldkl

回答

2

你必須使用退格鍵返回到前一個記錄。傳統的Fortran IO以創紀錄的,非基於流的(如在C)

+0

'backspace'的作品!謝謝。 – hatmatrix

1

在Linux和Windows,它是好的,一般的計算尋求補償。

但是,在面向記錄的文件系統(OpenVMS,OS/370,NOS等)上,來自ftell()的值是一個魔術餅乾,無法使用普通算法進行檢查或處理以計算新的文件位置。相反,使用rewind語句返回到文件的開頭(如果它確實是可搜索的)。

+0

感謝您對ftell的洞察 - 我認爲這是一個整數位置(就像emacs緩衝區中的一個點...)。我認爲'倒帶'的作品,但不能一路回去,因爲它是一個大文件只需要回去幾條記錄... – hatmatrix

1

有用於處理輸入,如果你不能確定該文件的內容的另一種技術 - 在這種情況下,有時文件內容不正確或不同 - 這是讀入一個字符串,然後檢查字符串的內容。如果內容有效,則可以使用讀取語句從字符串讀取。或者如果內容是「不同的」,請使用不同的讀取語句,或採取適當的措施。不需要倒退或退格。您必須猜測最長的行長來聲明字符串的長度。

+0

啊,像fortcan和fortran的東西...是的...不幸的是它是一個fortran未格式化的二進制文件,所以這種類型的操作會有點困難... – hatmatrix