OSU CSE 2421
Recommended Reading: Pointers On C, Chapter 13, Sections 13.4 through 13.4.2
J.E.Jones
OSU CSE 2421
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.
J. E. Jones
OSU CSE 2421
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
J. E. Jones
OSU CSE 2421
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).
J. E. Jones
OSU CSE 2421
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!
J. E. Jones
OSU CSE 2421
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’).
J. E. Jones
OSU CSE 2421
Consider: argv->
0x800540->”myProg”
0x800540 0x8012A0 0x800260 0x80200C 0x000000
540 541 542 543 544
545 546
argc = 4
Note: each individual string is in continuous memory locations, but each string can be in various locations
‘m’ ‘y’ ‘P’ ‘r’ ‘o’
‘g’ \0
0x8012A0->”16”
2A0 2A1 2A2
‘1’ ‘6’ \0
0x800260->”new”
260 261 262 263
‘n’ ‘e’ ‘w’ \0
0x80200C->”old”
00C 00D 00E 00F
‘o’ ‘l’ ‘d’ \0
J. E. Jones
OSU CSE 2421
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.
J. E. Jones
OSU CSE 2421
After the arguments are passed to main(), we can access them, just as any other function parameters:
#include
int main(int argc, char *argv[]) {
}
printf(“argv[%i]\t= %s\n”, i, argv[i]); return (0);
int i;
printf(“argc =\t%d\n”, argc); for (i = 0; i < argc; i++)
OR int main(int argc, char **argv) { char **ip = argv;
Notice first version uses argc to loop, the second uses the fact that argv[argc]==NULL
}
printf(“argv[%i]\t= %s\n”, i++, *ip++); return (0);
int i=0;
printf(“argc =\t%d\n”, argc); while(*ip!= NULL)
J. E. Jones
OSU CSE 2421
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
J. E. Jones
OSU CSE 2421
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.
J. E. Jones
OSU CSE 2421
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.
J. E. Jones
OSU CSE 2421
/* 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???
J. E. Jones
OSU CSE 2421
/* 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!!
J. E. Jones
OSU CSE 2421
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
J. E. Jones
OSU CSE 2421
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.
J. E. Jones