Command Line Arguments
A standard way to access a program's command line arguments wasn't added to Fortran until 2003. Command line arguments were one of those things (like environment variables, the file system, and the operating system shell) that the Fortran standards committee pretended didn't exist or wasn't important. Of course, that was and is ridiculous. So for decades, all Fortran compilers provided a non-standard way to get the command line arguments (for example, GETARG in gfortran). Currently, the standards committee still pretends that the file system doesn't exist (for example, there's no standard way to change an application's working directory, or list the files in a directory, or even to check for the existence of directories). But I digress.
The two routines you need to know are COMMAND_ARGUMENT_COUNT and GET_COMMAND_ARGUMENT. Frequently in examples on the internet (even the gfortran example) you will see people just declare a really long string and use GET_COMMAND_ARGUMENT to get the command line argument and hope for the best. That's terrible of course, since this routine does have the ability to return the actual length of the argument, so you should use that to allocate a string with the correct size to hold it.
Consider the following example:
module command_line_module
implicit none
private
type,public :: string
!! a variable-length string type
character(len=:),allocatable :: str
end type
public :: get_command_arguments
contains
subroutine get_command_arguments(nargs, args)
!! return all the command line arguments.
!! (each one is the correct size)
implicit none
integer,intent(out) :: nargs !! number of arguments
type(string),dimension(:),allocatable,intent(out) :: args
integer :: i, ilen
nargs = command_argument_count()
allocate(args(0:nargs))
do i = 0, nargs
call get_command_argument(i,length=ilen)
allocate(character(len=ilen) :: args(i)%str)
call get_command_argument(i,value=args(i)%str)
end do
end subroutine get_command_arguments
end module command_line_module
Here we have to define our own string type (string
), so we can create an array of deferred-length strings (since a useful varying-length string type is another thing Fortran pretends is not important). See StringiFor for a full-featured variable-string type, but for our purposes here the simple one is fine. The procedure in the get_command_arguments()
routine is to check for the size of each argument, allocate a string large enough to hold it, and then retrieve the value. It returns an array of string
variables containing the command line arguments. With a wrapper module like this, getting command line arguments is effortless, and there is no reason anymore to use the old non-standard routines.