20.2: Command Line Arguments
- Page ID
- 54388
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)The usage of command line arguments, information entered on the command line after the program name, can be very useful in specific circumstances. By allowing the user to provide some information on the command line, it saves the effort of entering the information interactively after the program starts. The term command line arguments is sometimes referred to as command line options.
For example, when starting a Fortran program for a simple game, the persons name could be provided on the command line. If the name is provided, the program could use that name. Otherwise, the program could use a generic name such as 'player'. The command line might appears as follows:
c:\fortran> tictactoe ed
On Unix based systems, this might be:
% ./tictactoe ed
Where tictactoe
is the name if the program and 'ed' is the single command line argument.
Multiple command line arguments can be provided, but must be separated with a space or multiple spaces. There is no predefined required format. The formatting or ordering requirements are up to the program.
The gfortran
compiler requires command line arguments for the various options including the input file name (i.e., tictactoe.f95
) and the output file name (i.e., -o tictactoe
) specification. For example,
c:\fortran> gfortran tictactoe.f95 -o tictactoe
For the gfortran
compiler, there is no required order for the command line arguments. However, a valid output file name must follow the '-o' argument.
The error handling for command line arguments is typically handled differently. Many programs check the command line arguments, and if incorrect for any reason, display an error message and terminate the program. This is what the gfortran
compiler does when invalid or incorrect arguments are provided.
It would be possible to create a program that could verify arguments, and if incorrect, display an error message and then request correct input from the user. The handling of the command line arguments processing is entirely the responsibility of the program and not the operating system.
Argument Count
There are generally two steps to obtaining the command line arguments. The first step is getting the argument count or the number of arguments entered on the command line. The previous tic-tac-toe
example has one argument (i.e., 'ed'). The previous gfortran
example had three (i.e., 'tictactoe.f95', '-o', and 'tictactoe').
The argument count is obtained using the command_argument_count()
system service as follows:
integer :: myCount myCount = command_argument_count()
Which will return the count in the variable myCount
(as shown above). The count will be zero if no arguments are entered.
Get Arguments
Once the argument count is available, the actual arguments can be obtained. The arguments are always returned as character values. If the argument is meant to be used as a real or integer value, it must be converted. The Character String / Numeric Conversions chapter provides a description of how this can be accomplished.
When obtaining the command line arguments, the get_command_argument()
system service is used. An argument is returned into a specified character variable. The character variable should be large enough (i.e., able to hold enough characters) to store the expected argument. The actual length of the returned argument can optionally be provided. Additionally, if the character variable is too small, the returned result will be truncated and the status set accordingly to indicate an error.
The options and associated values returned are described in the following table.
Option | Data Type | Description |
---|---|---|
length | integer | Input integer argument indicating which argument should be returned. Must be between 1 and the command_argument_count() value. |
value | character(*) | Output character variable of where to store the Nth argument as specified by the length value (above). The variable must be declared with an appropriate size. |
length | integer | Output integer argument for the actual length of the string returned by the value argument (above). |
status | integer | Output integer argument for the returned status value. A return status value of 0 is success and -1 is fail. |
The first two arguments are required and the final two arguments are optional.
Command Line Arguments, Example Program
This simple example obtains the command line argument count and displays the arguments to the screen for reference. In this example, the program will expect a real value as the first argument and an integer value as the second argument (if a second argument is provided). Any additional arguments, while not used, are still displayed the screen along with the argument count value.
For this example, since the number of arguments is unknown ahead of time, an array to hold the arguments is allocated at run-time. While this is not necessary, it does help provide a more complete example. Such a process would only be appropriate if a varying number of command line arguments is desired.
! Example program to demonstrate how to obtain the ! command line arguments from the system. program argsExample implicit none integer :: argCount, allocStatus, rdErr, i, iNum real :: rNum character(len=80), dimension(:), allocatable :: args ! ---------- ! Get command line argument count from system. argCount = command_argument_count() if (argCount == 0) then write (*,'(a)') "No command line arguments provided." stop end if ! ---------- ! Allocate an array to hold the arguments. allocate(args(argCount), stat=allocStatus) if (allocStatus > 0) then write (*,'(a)') & "Allocation error, program terminated." stop end if ! ---------- ! Get each argument, one at a time, from system. do i = 1, argCount call get_command_argument(number=i,value=args(i)) end do ! ---------- ! Display arguments to screen. if (argCount == 0) then write (*,'(a)') "No command line arguments provided." else if (argCount == 1) then write (*,'(a, i1, a)') "There was ", & argCount, " command line argument." else write (*,'(a, i2, a)') "There were ", & argCount, " command line arguments." end if write (*,'(/,a)') "The arguments were: " do i = 1, argCount write (*,'(a, a)') " ", trim(args(i)) end do write (*,*) end if ! ---------- ! Convert a string to a numeric value using an internal read. if (argCount >= 1) then read (args(1), '(f12.5)', iostat=rdErr) rNum if (rdErr == 0 ) then write (*,'(a, f12.5)') & "Argument 1 - Real Number = ", rNum else write (*,'(a)') "Error, invalid real value." end if end if if (argCount >= 2) then read (args(2), '(i10)', iostat=rdErr) iNum if (rdErr == 0 ) then write (*,'(a, i10)') & "Argument 2 - Integer Number = ", iNum else write (*,'(a)') "Error, invalid integer value." end if end if write (*,*) end program argsExample
An example of the output for this program with valid command line arguments provided is shown below. The executable name of the example program is 'args
'.
c:\fortran> args 3.14 23 hello world There were 4 command line arguments. The arguments were: 3.14 23 hello world Argument 1 - Real Number = 3.14000 Argument 2 - Integer Number = 23 c:\fortran>
Another example of the output for this program with invalid command line arguments provided is shown as follows:
c:\fortran> args 3.14 23 hello world There were 4 command line arguments. The arguments were: hello 3.14 23 world Error, invalid real value. Error, invalid integer value. c:\fortran>
Note, the order for the valid and invalid arguments was chosen arbitrarily.