2014-02-05 27 views
2

這是我的舊thread的延續。解析Fortran中的輸入文件

我有一個來自不同代碼的文件,我應該使用parse作爲我的輸入。 從它的片段看起來像:

GLOBAL SYSTEM PARAMETER 
NQ     2 
NT     2 
NM     2 
IREL    3 
************************************* 
BEXT  0.00000000000000E+00 
SEMICORE F 
LLOYD  F 
NE    32   0 
IBZINT    2 
NKTAB   936 
XC-POT VWN  
SCF-ALG BROYDEN2 
SCF-ITER   29 
SCF-MIX  2.00000000000000E-01 
SCF-TOL  1.00000000000000E-05 
RMSAVV  2.11362995016878E-06 
RMSAVB  1.25411205586140E-06 
EF   7.27534671479201E-01 
VMTZ  -7.72451391270293E-01 
************************************* 

等等。

目前我行看完一行,如:

Program readpot 
use iso_fortran_env 
Implicit None 
integer ::i,filestat,nq 
character(len=120):: rdline 
character(10)::key!,dimension(:),allocatable ::key 
real,dimension(:),allocatable ::val 
i=0 

open(12,file="FeRh.pot_new",status="old") 
readline:do 
    i=i+1 
    read(12,'(A)',iostat=filestat) rdline!(i) 

    if (filestat /= 0) then 
    if (filestat == iostat_end) then 
     exit readline 
    else 
     write (*, '(/ "Error reading file: ", I0)') filestat 
     stop 
    endif 
    end if 

    if (rdline(1:2)=="NQ") then 
    read(rdline(19:20),'(i)'),nq 
    write(*,*)nq 
    end if 
end do readline 

End Program readpot 

所以,我要讀每一行,手動查找對應的鍵的值列,並編寫(爲簡便起見,我有僅顯示一個值)。 我的問題是,這是正確這樣做?還是有其他更簡單的方法?請讓我知道。

+0

嗨@HighPerformanceMark,是的,格式和順序是***總是***相同。他們總是在場。它的另一個代碼的輸出,所以,位置是不可變的。 – BaRud

+1

如果這20行是代碼中的唯一行,那麼使用Fortran [namelist](http://www.sdsc.edu/~tkaiser/f90.html#)將數據轉儲到其他文件可能更容易一些名單),並使用它讀入你的代碼。 –

回答

5

如果文件沒有變化,你幾乎不需要解析它。假設您已經爲文件中所有感興趣的數據項聲明瞭變量,並且這些變量的名稱顯示在文件的行中。例如

INTEGER :: nq , nt, nm, irel 
    REAL:: scf_mix, scf_tol ! '-' not allowed in Fortran names 
    CHARACTER(len=48) :: label, text 
    LOGICAL :: semicore, lloyd 
    ! Complete this as you wish 

然後寫這樣

OPEN(12,file="FeRh.pot_new",status="old") 
    READ(12,*) ! Not interested in the 1st line 
    READ(12,*) label, nq 
    READ(12,*) label, nt 
    READ(12,*) label, nm 
    READ(12,*) label, irel 
    READ(12,*) ! Not interested in this line 
    READ(12,*) label, bext 
    READ(12,*) label, semicore 
    ! Other lines to write 
    CLOSE(12) 

的Fortran的列表定向輸入理解坯料中的行分離值的代碼塊。它不會將這些空白作爲字符變量的一部分來讀取。這種行爲可以改變,但在你不需要的情況下。請注意,當讀入邏輯變量時,它也將理解字符F以表示.false.

我的代碼片段只是忽略了標籤和解釋行。如果你是一個緊張的處置,你可以處理它們,也許

IF (label/='NE') STOP 

或任何你想要的。

+0

事實上,這是一種簡單的方式,是滿足要求的一種方法。我要說的(提問者)是:記錄它! – francescalus