Command-line environment
Command line arguments
C programs can receive arguments from the command line.
. /foo hello world
In the above example, the program foo
takes two command-line arguments, hello
and world
.
The C language takes the command line input and puts it in an array. The arguments to the main()
function can receive this array.
#include <stdio.h>
int main(int argc, char* argv[]) {
for (int i = 0; i < argc; i++) {
printf("arg %d: %s\n", i, argv[i]);
}
}
In the above example, the main()
function has two arguments argc
(argument count) and argv
(argument variable). The names of these two arguments can be arbitrary, but in general the convention is to use these two words.
The first argument, argc
, is the number of command line arguments, and since the program name is also counted, argc
is strictly speaking the number of arguments + 1.
The second argument, argv
, is an array holding all the command-line input, each member of which is a pointer to a string.
Take . /foo hello world
as an example, argc
is 3, which means that the command line input has three components: . /foo
, hello
, and world
. The array argv
is used to get these inputs, argv[0]
is the program name . /foo
, argv[1]
is hello
, and argv[2]
is world
. In general, argv[1]
to argv[argc - 1]
are all the arguments to the command line in that order. argv[argc]
is then a null pointer NULL.
Since string pointers can be thought of as arrays of characters, the following three ways of writing them are equivalent.
// Writing method one
int main(int argc, char* argv[])
// Write method two
int main(int argc, char* argv)
// Write method three
int main(int argc, char argv[][])
On the other hand, each command line argument can be written either as an array in the form argv[i]
or as a pointer in the form *(argv + i)
.
Using argc
, it is possible to limit the number of arguments a function can have.
#include <stdio.h>
int main(int argc, char** argv) {
if (argc ! = 3) {
printf("usage: mult x y\n");
return 1;
}
printf("%d\n", atoi(argv[1]) * atoi(argv[2]));
return 0;
}
The above example reports an error if argc
is not equal to 3
, which qualifies that the program must have two arguments in order to run.
Also, the last member of the argv
array is a NULL pointer (argv[argc] == NULL
). So, the traversal of arguments can also be written as follows.
for (char** p = argv; *p ! = NULL; p++) {
printf("arg: %s\n", *p);
}
In the above example, the pointer p
is moved sequentially, pointing to each member of argv
, and once it has moved to the null pointer NULL, the traversal is over. Since argv
has a fixed address and cannot perform a self-increment operation (argv++
), the traversal must be completed by an intermediate variable, p
.
Exit status
The C language specifies that if the main()
function does not have a return
statement, then the end of the run will by default add a return 0
, which returns the integer 0
. This is why the main()
statement usually agrees to return an integer value, and returns the integer 0
to indicate that the program ran successfully. If a non-zero value is returned, there is a problem with the program.
Bash's environment variable $?
can be used to read the return value of the previous command to know if it ran successfully.
$ . /foo hello world
$ echo $?
0
In the above example, echo $?
is used to print the value of the environment variable $?
, a value of 0
means that the previous command ran successfully, otherwise it failed.
Note that only main()
adds return 0
by default, none of the other functions have this mechanism.
Environment variables
The C language provides the getenv()
function (prototype in stdlib.h
) for reading command-line environment variables.
## include <stdio.h>
#include <stdlib.h>
int main(void) {
char* val = getenv("HOME");
if (val == NULL) {
printf("Cannot find the HOME environment variable\n");
return 1;
}
printf("Value: %s\n", val);
return 0;
}
In the above example, getenv("HOME")
is used to get the command line environment variable $HOME
, if this variable is empty (NULL
), the program returns with an error.