This is a small library that I use to make the input and output routines of FORTRAN a little easier to handle. So far, it’s quite unsophisticated, but I welcome improvements here.
The main features are: * easy and intelligent input of command line arguments, * simple file opening and unit tracking.
I should point out that due to the use of getarg()
, the code is not strictly F95.
Compile the code and link it to your current program. You also need to make sure that the .mod
file is accessible by the program. The library can be included in the main program simply by using
use mm_ioutils
In order to read command line arguments into program variables, use the read_argument()
subroutine. This takes two arguments: the first is the index of the argument on the command line (counting from 1), and the second is the variable that is to be written to (this must be of type integer
, real
or double precision
).
! example
program example
use mm_ioutils
implicit none
integer :: test_int
call read_argument(1, test_int)
write (*,*) test_int
end program example
Compiling and then running the program as example 10
should then simply print the number 10 to the console.
The function open_file(name, st)
opens a file with the prefix name
(note that this may include a path) and with an optional status string st
. The function returns the file unit identifier.
! example
program example
use mm_ioutils
implicit none
integer :: FTEST
FTEST = open_file("my_dir/my_file.txt")
write (FTEST, *) "Hello World!"
end program example
Note that in the above example, since we did not specify st
, the file was opened with status “unknown”. Secondly, the directory my_dir
must exist in the path where the program is run.
The function open_fileset(name, n)
behaves similarly to open_file
, except it opens a set of N files with successive unit identifiers, and all with status “unknown”. The returned integer is the unit identifier of the first opened file.
Finally, one can also set the prefix used by default for all files (this is useful for specifying a common subdirectory) by using the io_set_prefix
command. For example, calling
call io_set_prefix("my_dir")
will place all subsequently created files in the subdirectory “my_dir” of the directory where the program is being run.
!
! mm_ioutils.f90
! A set of file handling routines
!
! Michael Murphy, Mar. 2009
!
module mm_ioutils
implicit none
interface read_argument
module procedure read_argument_int
module procedure read_argument_float
module procedure read_argument_float_dp
end interface
private
integer :: nextunit=10
character(50) :: fileprefix=""
public :: open_file, open_fileset, read_argument, io_set_prefix
contains
! ------------------------------------------------------------------------------
! function open_file
! opens a file with "unknown" status and returns the unit number
function open_file(name, st) result (id)
character(*), intent(in) :: name
character(*), optional :: st
integer :: id
id = nextunit
nextunit = nextunit + 1
if (.not.present(st)) then
open (unit=id, file=trim(fileprefix)//name//".txt", status="unknown")
else
open (unit=id, file=trim(fileprefix)//name//".txt", status=st)
end if
end function open_file
! ------------------------------------------------------------------------------
! function open_fileset
! opens a set of files with numerical suffices and with "unknown" status
function open_fileset(basename, n) result (id)
character(*), intent(in) :: basename
integer, intent(in) :: n
character(3) :: suffix
integer :: id, i
if (n.gt.999) then
write (*,*) "mm_fileio: More than 999 files required -- aborting"
stop
end if
id = nextunit
nextunit = nextunit + n
do i=1,n
write (unit=suffix, fmt='(I3)') i
open (unit=id+(i-1), file=trim(fileprefix)//trim(basename)//"_"//trim(adjustl(suffix))//".txt", status="unknown")
end do
end function open_fileset
! ------------------------------------------------------------------------------
! subr read_argument_int
! reads an integer from the command line and inserts it into a variable
subroutine read_argument_int(index, var)
integer, intent(in) :: index
integer, intent(inout) :: var
character(12) :: arg
call getarg(index, arg)
if (arg.ne."".and.arg.ne."?") then
read(unit=arg, fmt='(I6)') var
end if
end subroutine read_argument_int
! ------------------------------------------------------------------------------
! subr read_argument_float
! reads a float from the command line and inserts it into a variable
subroutine read_argument_float(index, var)
integer, intent(in) :: index
real, intent(inout) :: var
character(12) :: arg
call getarg(index, arg)
if (arg.ne."".and.arg.ne."?") then
read(unit=arg, fmt='(F20.9)') var
end if
end subroutine read_argument_float
! ------------------------------------------------------------------------------
! subr read_argument_float_dp
! reads a real(8) from the command line and inserts it into a variable
subroutine read_argument_float_dp(index, var)
integer, intent(in) :: index
real(8), intent(inout) :: var
character(12) :: arg
call getarg(index, arg)
if (arg.ne."".and.arg.ne."?") then
read(unit=arg, fmt='(F20.9)') var
end if
end subroutine read_argument_float_dp
! ------------------------------------------------------------------------------
! subr io_set_prefix
! set a common prefix for all filenames
subroutine io_set_prefix(prefix)
character(*), intent(in) :: prefix
fileprefix = prefix
end subroutine io_set_prefix
end module mm_ioutils