解析fortran中的输入文件

BaR*_*Rud 2 parsing 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 
************************************* 
Run Code Online (Sandbox Code Playgroud)

等等.

目前我正在逐行阅读,如:

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 
Run Code Online (Sandbox Code Playgroud)

所以,我必须读取每一行,手动找到与该键对应的值列,并写入(为简洁起见,我只显示了一个值).我的问题是,这是正确的做法吗?还是有其他更简单的方法?请告诉我.

Hig*_*ark 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
Run Code Online (Sandbox Code Playgroud)

然后写一个像这样的代码块

  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)
Run Code Online (Sandbox Code Playgroud)

Fortran的列表导向输入理解行中的空白以分隔值.它不会将这些空格读作字符变量的一部分.这种行为可以改变,但在你的情况下,你不需要.请注意,在读入逻辑变量时,它还将理解F要表示的字符.false..

我的代码片段忽略了标签和解释线.如果你是一个紧张的性格,你可以处理它们

IF (label/='NE') STOP
Run Code Online (Sandbox Code Playgroud)

或者你想要什么.