Microsoft PowerPoint – 14_Command_Line_Args_In_C
O
SU
C
SE
2
42
1
J.E.Jones
Recommended Reading: Pointers On C, Chapter 13,
Sections 13.4 through 13.4.2
O
SU
C
SE
2
42
1
J. E. Jones
We know that, when we call a function in a C
program, arguments can be passed to the function.
When we execute a C program from the command
line, we can also pass arguments to main().
Let’s see how this is done.
O
SU
C
SE
2
42
1
J. E. Jones
main() is invoked when we run a command on the command
line to execute a C program. For example, for a program called
myProg:
% myProg
If we want to pass arguments, or parameters, say p1, p2, and
p3, to main() in myProg, we enter them on the command line
after the name of the program:
% myProg p1 p2 p3
then, we’ll declare main with parameters so we can access
them
O
SU
C
SE
2
42
1
J. E. Jones
Any arguments passed from the command line will be placed in read-only
memory.
◦ Remember string-literals are put there, too
If we want to pass arguments to main() from the command line, we have
two appropriate declarations of the parameters for main() inside the
program:
int main(int argc, char **argv) { … }
int main(int argc, char *argv[]) { … }
One of these approaches uses a pointer to a pointer to char for the 2nd
parameter and the other uses an array of char pointers.
These two declarations are equivalent (they are just different ways of
looking at the same thing – more explanation below).
O
SU
C
SE
2
42
1
J. E. Jones
The parameters given on the command line are passed to a C program using two
variables, which have the following names, by convention:
1. argc contains the count of the command line arguments. Think “argcount” or
“argument count”
2. argv contains pointers to the individual arguments as character strings (argv[] is
an array of char *). Think “argvector” or “argument vector”.
A conclusion you might make (and you’d be right) is that, since “argv points to
individual arguments as character strings”, ALL command line arguments enter a
C program as ASCII strings!
In the declaration of main(), the names of argc and argv may be any valid identifiers
in C, but it is a common convention to use these names.
NOTE!!: There is no guarantee that the strings pointed to by the pointers in argv are
stored in contiguous locations in memory, as they would be in a normal array,
because argv is an array of pointers to these strings!
O
SU
C
SE
2
42
1
J. E. Jones
Again, suppose that, at the command line prompt, we enter:
% myProg 16 new old
This results in argc containing the value 4 and the following strings to which the
elements of argv point, because argv[] is an array of char * (or a char **):
argv[0] points to “myProg\0” /*string with program name */
argv[1] points to “16\0”
argv[2] points to “new\0”
argv[3] points to “old\0”
argv[4] is a NULL pointer
Note that, because these strings are of type char *, they are stored in read only
memory, and any attempt to write to them will result in a segmentation fault!
Also note that each argument is an ASCII string terminated by a NULL byte (‘\0’).
O
SU
C
SE
2
42
1
J. E. Jones
Consider:
argv-> 0x800540->”myProg”
0x8012A0->”16”
0x800260->”new”
0x80200C->”old”
argc = 4
Note: each individual string is in continuous memory locations, but each string can be in various locations
0x800540
0x8012A0
0x800260
0x80200C
0x000000
540 541 542 543 544 545 546
‘m’ ‘y’ ‘P’ ‘r’ ‘o’ ‘g’ \0
2A0 2A1 2A2
‘1’ ‘6’ \0
260 261 262 263
‘n’ ‘e’ ‘w’ \0
00C 00D 00E 00F
‘o’ ‘l’ ‘d’ \0
O
SU
C
SE
2
42
1
J. E. Jones
Recall that any array may be viewed as a (constant) pointer to
the first element of the array.
For this reason, argv can be declared in one of two ways:
int main(int argc, char *argv[]);
int main(int argc, char **argv);
Thus, argv may be viewed as an array of char *, or as a char
** (a pointer to a pointer to char).
Which way you choose to declare it in your programs is up to
you. Pick the way that is easier for you to visualize your data.
O
SU
C
SE
2
42
1
J. E. Jones
After the arguments are passed to main(), we can access them, just as any other
function parameters:
#include
int main(int argc, char *argv[]) {
int i;
printf(“argc =\t%d\n”, argc);
for (i = 0; i < argc; i++)
printf(“argv[%i]\t= %s\n”, i, argv[i]);
return (0);
}
OR int main(int argc, char **argv) {
char **ip = argv;
int i=0;
printf(“argc =\t%d\n”, argc);
while(*ip!= NULL)
printf(“argv[%i]\t= %s\n”, i++, *ip++);
return (0);
}
Notice first version uses argc to loop, the second uses the fact that argv[argc]==NULL
O
SU
C
SE
2
42
1
J. E. Jones
For the command line input: “myProg 16 new old”
The programs on the previous slide both print:
argc = 4
argv[0] = myProg
argv[1] = 16
argv[2] = new
argv[3] = old
O
SU
C
SE
2
42
1
J. E. Jones
The name of the program, argv[0], can be useful when printing diagnostic
or error messages. Usually, multiple processes (or programs) are running
on the system, so it is useful to be able to identify which process caused an
error.
printf(“myProg expects 3 parameters, only %d were entered\n”, argc-1);
or a better way…
printf(“%s expects 3 parameters, only %d were entered\n”, argv[0], argc-1);
The second option allows for the myProg executable to be copied to
another filename. (e.g. cp myProg sumProg). If we use the 2nd option
when using the program with its new name (sumProg), the error
message is still correct.
The values of the other parameters can be accessed and used just as any
other function parameters.
O
SU
C
SE
2
42
1
J. E. Jones
It is guaranteed that argc is non-negative, and that argv[argc] is a NULL
pointer.
By convention, the command line arguments specified by argc and argv
include the program name as the string that is pointed to by argv[0].
For example, if a user types the command “rm file”, the shell will initialize
the rm process with argc = 2, argv[0] as “rm”, and argv[1] as “file”, and
argv[2] as 0 [the value of a NULL pointer].
Remember that the main() function is special. Every C program must
define it exactly once.
O
SU
C
SE
2
42
1
J. E. Jones
/* sum.c sum n1 n2 n3… =>n1+n2+…
** This program sums the integer values that correspond to the
** strings from argv[1] to argv[argc – 1] */
#include
int main(int argc, char *argv[]){
int i;
int sum = 0;
for (i = 1; i < argc; i++){
sum = sum + ( atoi (argv[i]) ); /* atoi() converts an ASCII string to an int */
}
printf(“The sum of the command line arguments after the first is %i.\n”,
sum);
return (0);
}
Why do we need to use the atoi() function???
O
SU
C
SE
2
42
1
J. E. Jones
/* sum.c
** This program sums the integer values that correspond to the
** strings from argv[1] to argv[argc – 1] */
#include
int main(int argc, char *argv[]){
int i;
int sum = 0;
for (i = 1; i < argc; i++){
sum = sum + ( atoi (argv[i]) ); /* atoi() converts an ASCII string to an int */
}
printf(“The sum of the command line arguments after the first is %i.\n”, sum);
return (0);
}
Why do we need to use the atoi() function???
ALL parameters are ASCII strings!!
O
SU
C
SE
2
42
1
J. E. Jones
int atoi() – convert ASCII string to 4-byte integer data type
long atol() – convert ASCII string to 8-byte integer data type
long long atoll() – convert ASCII string to 16-byte integer data
type (C99 and above)
double atof() – convert ASCII string to 8-byte floating point
data type
◦ float f = (float)atof(); if you want a 4-byte floating point
data type
O
SU
C
SE
2
42
1
J. E. Jones
Now, after compiling the program, suppose we enter
on the command line:
% sum 100 50 25
The program prints out:
The sum of the command line arguments after the first is 175.