Menu

Command Line Arguments in C: argc, argv, and Parsing Them Safely

How a C program reads its command line - the anatomy of argc and argv, iterating the arguments, what argv[0] holds, converting numbers with strtol instead of atoi, and a small calculator that puts it together.

This page includes runnable editors - edit, run, and see output instantly.

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:

IndexValue
argv[0]"./greet"the program name as invoked
argv[1]"Ada"first real argument
argv[2]"Lovelace"second real argument
argv[3]NULLthe terminator
argc3count including argv[0]

Four facts worth committing:

  • argc is at least 1 in practice, because argv[0] is the program name. Real arguments start at index 1, which is why loops over them start at i = 1.
  • Everything is a string. ./prog 42 gives you "42", the two characters, never the number 42. Converting is your job.
  • argv[argc] is NULL. Guaranteed by the standard, so you can walk the array without argc if 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 reach argv.

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, not stdout, so it does not pollute output being piped somewhere.
  • A non-zero return from main signals failure to whatever ran the program. 0 means 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 == text means 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 == ERANGE means the value overflowed long.

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 checking argc. 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 atoi on user input. No way to tell a bad argument from a zero.
  • Comparing strings with ==. Use strcmp.
  • Writing into argv strings. 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.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED