这是我旧线程的延续.
我有一个来自不同代码的文件,我应该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)
所以,我必须读取每一行,手动找到与该键对应的值列,并写入(为简洁起见,我只显示了一个值).我的问题是,这是正确的做法吗?还是有其他更简单的方法?请告诉我.
如果文件没有可变性,则根本不需要解析它.假设您已为文件中的所有有趣数据项声明了变量,并且这些变量的名称显示在文件的行上.例如
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)
或者你想要什么.