2014-02-05 3 views
2

이것은 내 오래 된 thread의 연속입니다.포트란에서 입력 파일을 구문 분석합니다.

다른 코드의 파일이 있습니다. 입력 한 내용을 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#)을 사용하여 추가 파일로 데이터를 덤프하는 것이 더 쉬울 수도 있습니다 Namelist)를 사용하여 코드로 읽습니다. –

답변

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) 

포트란 에서 지시 등을 입력 코드 블록 값을 구분하는 라인 블랭크 이해 물품. 문자 변수의 일부로 해당 공 i을 읽지 않습니다. 그 행동은 변경 될 수 있지만 귀하의 경우에는 그렇게 할 필요가 없습니다. 논리 변수로 읽을 때 F 문자는 .false.을 의미하는 것으로 이해해야합니다.

내 코드 조각은 설명의 레이블과 라인을 무시합니다. 신경질적인 성향의 사람들은 아마도 처리 할 수 ​​있습니다. 아마도

IF (label/='NE') STOP 

또는 원하는 것을 선택하십시오.

+0

실제로 이것은 매우 단순한 방법이며 요구 사항에 대한 적절한 방법입니다. 내가 (asker에게) 말할 수있는 것은 : 그것을 문서화하십시오! – francescalus

관련 문제