How Can I Modify My Fortran Code to Correctly Read an .xvg File?

  • Thread starter Thread starter anupama sharma
  • Start date Start date
  • Tags Tags
    File Reading
AI Thread Summary
The discussion centers on writing a Fortran code to read numeric data from an .xvg file that contains initial character lines followed by numeric data. The original code successfully reads data but requires modification for each new file. Suggestions include using character arrays to allow user input for file names, which would generalize the code. A revised code snippet demonstrates how to prompt for input and output file names, open the files accordingly, and handle reading errors. The conversation also addresses runtime errors encountered during compilation, emphasizing the importance of correctly managing file opening and reading operations. The proposed solution aims to streamline the process and improve user experience by allowing dynamic file handling.
anupama sharma
Messages
8
Reaction score
1
TL;DR Summary
I need help in writing a Fortran code to read in the numeric data, but the file contains some character in few initial lines and later the numeric data has been written. please help me in writing the Fortran code. I will be thankful for the kind help......
I need help in writing a Fortran code to read in the numeric data, but the file contains initially some character in few initial lines and later the numeric data has been written. please help me in writing the Fortran code. I will be thankful for the kind help...
 
Technology news on Phys.org
Maybe you can try to put an if statement to identify the difference between string and int
anupama sharma said:
but the file contains initially some character in few initial lines and later the numeric data has been written.
 
hello friends,
I have written a small Fortran code to read the *.xvg file and extract the numeric data and it is working well but each time I have to modify the loop in order to read another *.xvg file. Can anybody help me in writing a more general code for the requisite work?

here is my code

Fortran:
program readxvg
      implicit none
      real (kind=4) x,y
      integer :: lskip,lread
      open (unit=10, file='rdf_42_OW_OW.xvg',action='read')
      open (unit=11,file='rdf_42_OW_OW.out',action='write')
      DO lskip = 1,24
         READ(10,*)
         enddo
         do lread=1,1834
      read (10,*)x,y
      write (11,30)x,y
      30 format (6x,f5.3,4x,f5.3)
      enddo
      close(10)
      end program readxvg
and here is sxvg file I am working with

Fortran:
# This file was created Mon May 20 10:55:52 2019
# Created by:
#                    :-) GROMACS - gmx rdf, VERSION 5.1.4 (-:
#
# Executable:   /home/sudip/Desktop/softwares/gromacs/5.1.4/gmx_installed/bin/gmx
# Data prefix:  /home/sudip/Desktop/softwares/gromacs/5.1.4/gmx_installed
# Command line:
#   gmx rdf -f ../../traj_mod/trjconv_ctab42_nopbc.trr -s ../../../256/mdrun/em.tpr -n ../../index/N_headgrp.ndx -o rdf_42_OW_OW.xvg
# gmx rdf is part of G R O M A C S:
#
# Great Red Oystrich Makes All Chemists Sane
#
@    title "Radial distribution"
@    xaxis  label "r (nm)"
@    yaxis  label "g(r)"
@TYPE xy
@ subtitle "reference Water_&_OW"
@ view 0.15, 0.15, 0.75, 0.85
@ legend on
@ legend box on
@ legend loctype view
@ legend 0.78, 0.8
@ legend length 2
@ s0 legend "Water_&_OW"
      0.000    0.000
      0.002    0.000
      0.004    0.000
      0.006    0.000
      0.008    0.000
      0.010    0.000
      0.012    0.000
      0.014    0.000
      0.016    0.000
      0.018    0.000
      0.020    0.000
      0.022    0.000
      0.024    0.000
      0.026    0.000
      0.028    0.000
      0.030    0.000
      1.032    0.000
 
Last edited by a moderator:
anupama sharma said:
I have written a small Fortran code to read the *.xvg file and extract the numeric data and it is working well but each time I have to modify the loop in order to read another *.xvg file. Can anybody help me in writing a more general code for the requisite work?
Here's one solution that would allow you to enter the filename of one .xvg file at a time.
Declare two character arrays of size about 30 characters in the part of your program where you declare x, y, lskip, and lread. You could call them fnameInput and fnameOutput.
Before the start of the loop body, prompt the user to enter the name of the file to read, and the name of the output file, and store these in the two variables. Use the fnameInput value in the line where you open the input file, and use fnameOutput in the line where you open the output file.

The code would look something like this:
Fortran:
program readxvg
      implicit none
      real (kind=4) x,y
      integer :: lskip,lread
      character(len = 30) fnameInput, fnameOutput              ! Added
     
      write(*, *) 'Enter the name of the input .xvg file: '        ! Added
      read (*, *) fnameInput                                                        ! Added

      write(*, *) 'Enter the name of the output file: '             ! Added
      read (*, *) fnameOutput                                                    ! Added
      open (unit=10, file=fnameInput,action='read')              ! Changed
      open (unit=11,file=fnameOutput',action='write')          ! Changed
      DO lskip = 1,24
         READ(10,*)
         enddo
         do lread=1,1834
      read (10,*)x,y
      write (11,30)x,y
      30 format (6x,f5.3,4x,f5.3)
      enddo
      close(10)
end program readxvg

I don't have a Fortran compiler, so I can't verify that the above will compile correctly, but the basic idea is OK.

If you need to process multiple input files, you could embed the lines between the first write statement and the final close statement in a while loop, exiting it when the user enters a file name that is an empty string.

BTW, you are closing unit 10 -- you should also close unit 11.
 
Thanks for your reply..
But this doesn't seems to work...
 
Whenever i compile the code it shows error
 
anupama sharma said:
Whenever i compile the code it shows error
What is the compiler error message, and what line does the compiler say the error is on? A screen shot of the error message would be helpful.
 
Here I am attaching the fortran code and also the screen shot of error message...

program readxvg
implicit none
real (kind=4) x,y
integer :: lskip,lread
character(len=30) :: infile,outfile,newfile
integer :: nvals =0
integer :: sta
real :: valu

write(*, *) 'Enter the name of the input .xvg file: '
read (*, *) infile

write(*, *) 'Enter the name of the output file: '
read (*, *) outfile

open(unit=12,file='infile',status='old',action='read',iostat=sta)
open (unit=11,file='outfile',action='write')
openif: if (sta==0) then
DO lskip = 1,24
READ(12,*)
enddo
readloop: do
read(12,*,iostat=sta) x,y
write (11,*)x,y
if (sta/=0) exit
nvals=nvals+1
enddo readloop
readif: if (sta>0) then ! a read error occured. Tell user.
Write(*,32)nvals+1
32 format (2x,'An error occurred reading line',i6)
else ! the end of data has reached. tell user
write(*,33) nvals
33 format (2x,'End of file reached. There were ',i6,&
' values in the file.')
endif readif
else openif
write (*,34) sta
34 format (2x,'error opening file: iostat = ',i6)
endif openif
close (unit=12)
close (unit=11)

end program readxvg
 

Attachments

  • readxvg.png
    readxvg.png
    9.5 KB · Views: 241
anupama sharma said:
Whenever i compile the code it shows error
The screen shot you posted is **not** a compile error. It was an error that occurred at run time. I am adding code tags around the code you posted, below. I'm also making significant changes to your code to make it easier to read.

Again, I don't have a Fortran compiler, so can't verify that there aren't any small errors in this code, but it should be fairly close to what you're trying to do.
anupama sharma said:
Here I am attaching the fortran code and also the screen shot of error message...
Fortran:
program readxvg
      implicit none
      real (kind=4) x, y
      integer :: lskip, lread
      character(len=30) :: infile, outfile
      integer :: nvals =0
      integer :: sta = 0
    
      write(*, *) 'Enter the name of the input .xvg file: '
      read (*, *) infile

      write(*, *) 'Enter the name of the output file: '
      read (*, *) outfile

      open(unit=12,file='infile', status='old', action='read', iostat=sta)
      open (unit=11,file='outfile', action='write')
      if (sta > 0) then  ! File could not be opened. Tell user.
                Write(*, *) 'Error opening the input file'
                exit
      endif
 
      DO lskip = 1,24
            READ(12, *)
      enddo

      do
           read(12,*,iostat=sta) x, y
           nvals = nvals + 1         
           if (sta < 0) then      ! the end of data has reached. tell user
                write(*,33) nvals
                33 format (2x,'End of file reached. There were ',i6,&
                              ' values in the file.')
                exit
           endif
           write (11,*)x, y          
      enddo

      close (unit=12)
      close (unit=11)
end program readxvg
 
Last edited:
  • Like
Likes sysprog

Similar threads

Replies
12
Views
3K
Replies
5
Views
5K
Replies
5
Views
2K
Replies
1
Views
3K
Replies
4
Views
1K
Replies
16
Views
4K
Replies
2
Views
1K
Replies
3
Views
3K
Back
Top