Every program you run from a terminal can be handed arguments: gcc -Wall hello.c -o hello passes four of them. Your own C programs read theirs through two parameters on main, and that is the whole mechanism - no library call, no setup.
The Signature
So far every example in these docs has used int main(void). The other standard form takes the command line:
int main(int argc, char *argv[]) {
/* ... */
}
argc("argument count") is how many arguments there are, including the program name.argv("argument vector") is an array of strings.char *argv[]means "array of pointers to char", which is an array of C strings.
char **argv is an equivalent spelling you will see just as often; array parameters decay to pointers, so the two declare the same thing.
Use the editor's Args panel to supply arguments (each field is one argument), then Run. Try three fields: hello, world, 42.
The Anatomy
Running ./greet Ada Lovelace produces:
| Index | Value | |
|---|---|---|
argv[0] | "./greet" | the program name as invoked |
argv[1] | "Ada" | first real argument |
argv[2] | "Lovelace" | second real argument |
argv[3] | NULL | the terminator |
argc | 3 | count including argv[0] |
Four facts worth committing:
argcis at least 1 in practice, becauseargv[0]is the program name. Real arguments start at index 1, which is why loops over them start ati = 1.- Everything is a string.
./prog 42gives you"42", the two characters, never the number 42. Converting is your job. argv[argc]isNULL. Guaranteed by the standard, so you can walk the array withoutargcif you prefer:for (char **p = argv + 1; *p != NULL; p++).- The shell splits the words, not your program.
./prog "Ada Lovelace"is one argument; the quotes are consumed by the shell and never reachargv.
Checking Before You Read
An argument that was not passed is not an empty string - it is memory you have no right to touch. Always validate argc first:
Two conventions in that tiny program, both standard across Unix tools:
- The usage message goes to
stderr, notstdout, so it does not pollute output being piped somewhere. - A non-zero return from
mainsignals failure to whatever ran the program.0means success; anything else means something went wrong. Shell scripts check it.
Printing argv[0] rather than a hard-coded name means the message matches however the user invoked the program, even if it was renamed or reached by a different path.
Converting Numeric Arguments
argv[1] is text. To do arithmetic you must convert it, and the function to use is strtol from <stdlib.h>:
Add 10, 20, 30 as three Args fields, then swap one for banana to see the error path.
The third parameter of strtol is the base: 10 for decimal, 16 for hex, or 0 to auto-detect from a 0x or leading-zero prefix. The second is where to store a pointer to the first character it did not consume, and that is what makes error checking possible:
end == textmeans it parsed nothing - the argument did not start with a number.*end != '\0'means there was leftover text after the number, so"12abc"is rejected rather than quietly becoming 12.errno == ERANGEmeans the value overflowedlong.
Compare with atoi, which is shorter and cannot report any of this:
int n = atoi(argv[1]); /* "banana" -> 0, "0" -> 0, overflow -> undefined */
atoi returns 0 for invalid input, which is indistinguishable from a genuine zero. Use strtol (and strtod for floating point) whenever the input comes from outside your program. More in string conversion.
A Small Calculator
Putting it together - a program taking a number, an operator, and a number:
Try 12 + 30, then 7 x 6, then 5 / 0.
Note strcmp(op, "+") == 0 rather than op == "+". Comparing char * values with == compares addresses, not contents, and would be false even for identical text. See string functions.
The x instead of * is a real-world detail: most shells expand a bare * into the list of files in the current directory before your program ever runs. Quoting it ('*') works too, but choosing a character the shell ignores is friendlier.
Parsing Flags
Options conventionally start with -. A simple hand-rolled loop handles the common cases:
Try it with four Args fields: -v, -n, 3, hello.
The i + 1 >= argc check before argv[++i] is the important line: an option expecting a value must confirm the value is actually there, or -n as the last argument reads past the end of the array. On real Unix systems getopt from <unistd.h> does all this for you, including bundled short options like -vn3; it is worth reaching for once a program has more than two or three flags.
Arguments in the Browser Editor
The editor blocks on this page are compiled and run for you, and the Args panel is where you supply what would follow the program name in a terminal. Each field you add with Add arg becomes exactly one entry in argv - there is no shell in between, so nothing is split on spaces and no quoting is needed: a field containing hello world arrives as the single argument hello world. To pass -n 3 hello, add three fields. Leaving the panel empty gives argc == 1 - which is why the argc < 2 guard fires on a first run, and why it is worth writing.
Common Mistakes
- Reading
argv[1]without checkingargc. Undefined behavior when no arguments were passed - and the most common crash in this area. - Starting the loop at
i = 0. That processes the program name as if it were data. - Treating
argv[1]as a number. It is text until you convert it. - Using
atoion user input. No way to tell a bad argument from a zero. - Comparing strings with
==. Usestrcmp. - Writing into
argvstrings. Modifying them is allowed by the standard but the space is limited and platform-dependent; copy into your own buffer if you need to change something.
Frequently Asked Questions
What are argc and argv in C?
They are the two parameters of int main(int argc, char *argv[]). argc is the number of command line arguments including the program name; argv is an array of those arguments as strings. argv[0] is the program name, argv[1] is the first real argument, and argv[argc] is always NULL.
How do you pass arguments to a C program?
Type them after the executable name in the terminal: ./program hello 42. That gives argc == 3, with argv[1] the string "hello" and argv[2] the string "42". In the editor on this page, arguments go in the Args panel instead of a terminal.
How do you convert a command line argument to an int in C?
Use strtol: char *end; long n = strtol(argv[1], &end, 10); then check that end is not still pointing at the start (nothing parsed) and that *end is '\0' (no trailing junk). atoi is shorter but returns 0 for both "0" and "banana", so it cannot report an error.
What is argv[0] in C?
The name the program was invoked with - typically ./program or the full path. It is useful in usage messages (fprintf(stderr, "usage: %s FILE\n", argv[0])) so the message matches how the user actually called it. It can be an empty string in unusual cases, so do not assume it is present.