2

This is a continuation of my older thread.

I have a file from different code, that I should parse to use as my input. A snippet from it looks like:

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 
************************************* 

And so on.

Currently I am reading it line by line, as:

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 

So, I have to read every line, manually find the value column corresponding to the key, and write that(For brevity, I have shown for one value only). My question is, is this the proper way of doing this? or there is other simpler way? Kindly let me know.

2
  • Hi @HighPerformanceMark, yes, the format and order is always same. and they are always present. Its output of another code, so, positions are NOT variable. Commented Feb 5, 2014 at 15:49
  • 1
    If those 20 lines are the only lines present in the code, it might be easier just to dump the data to an extra file using Fortran namelist and read it into your code using that. Commented Feb 5, 2014 at 16:18

1 Answer 1

5

If the file has no variability you scarcely need to parse it at all. Let's suppose that you have declared variables for all the interesting data items in the file and that those variables have the names shown on the lines of the file. For example

  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

Then write a block of code like this

  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's list-directed input understands blanks in lines to separate values. It will not read those blanks as part of a character variable. That behaviour can be changed but in your case you don't need to. Note that it will also understand the character F to mean .false. when read into a logical variable.

My code snippet just ignores the labels and lines of explanation. If you are of a nervous disposition you could process them, perhaps

IF (label/='NE') STOP

or whatever you wish.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.