Search code examples
fortrancommand-line-arguments

How to get command line arguments in Fortran


I know how to get simple command line arguments in Fortran using the function GET_COMMAND_ARGUMENT() like this:

program silly_app    

character(len=10)       :: arg
integer                 :: i, x

do i = 1, command_argument_count()
  call GET_COMMAND_ARGUMENT(i, arg)

  select case (arg)
  case ('-s', '--SA')
      x = 0
  case ('-f', '--FEWS')
      x = 1
  end select
enddo

end program

However, what I want to achieve is to parse an argument via the command line and read a string after that certain argument. The program should be called like this:

silly_app.exe -f -p "C:\TEMP\"

where the -p argument causes the program to read the argument "C:\TEMP" to a variable that is used inside the program.


Solution

  • When you have your loop like

    do i = 1, command_argument_count()
    end do
    

    you are saying that you are expecting to do the loop body a number of times equal to the result of command_argument_count() (the number of arguments on the command line). That's one way to do things, certainly.

    But your number of iterations may actually be better considered as not known in advance. After all, you may want to consider two (or more) arguments as a set. Such as -p string being a pair.

    This is a loop with indefinite iteration count1:

    i=0
    do
      i=i+1
      if (i.gt.command_argument_count()) exit
    end do
    

    Phrased that way, we can say:

    character(:), allocatable :: arg, pstr  ! For F2023 get_command_argument
    integer i
    
    i=0
    do
      i=i+1
      if (i.gt.command_argument_count()) exit
    
      call get_command_argument(i, arg)
      if (arg=='-p') then
        i=i+1
        call get_command_argument(i, pstr)
      end if
    end do
    

    This can be tidied up a lot and can be written with select case and have the other options handled. Deferred-length characters are good, but you may need to use them slightly differently from shown here.

    This other question's answers give good tips, too.


    1 Recall that in a loop with a control variable, like do i=..., we cannot skip an iteration by incrementing the control variable within the loop body. This is why i here is handled in this more cumbersome way.