Skip to content
FollowtheDamnCode

Command-Line Arguments

argc, argv, and reading words typed after the program's name.

6 minute read

Big idea

When you start a program from a terminal you can pass it words: ./greet Asha. C hands them to main as argc (how many) and argv (the words themselves, as strings).

The idea

So far main has taken nothing: int main(void). It can instead take two parameters:

int main(int argc, char *argv[])
  • argc — argument count: how many words were typed, including the program's name.
  • argv — argument vector: an array of strings. argv[0] is the program name, argv[1] the first real argument, and so on. argv[argc] is always NULL.

Running ./greet Asha 21 gives:

value
argc3
argv[0]"./greet"
argv[1]"Asha"
argv[2]"21" — still a string, not a number

What argv looks like in memory

argv is an array of pointers; each points to the first character of one word. The lesson runner can't type a command line, so this program builds the same thing by hand and passes it on:

In a real program you'd write int main(int argc, char *argv[]) and use them directly — the code inside is the same.

Always check argc first

If the user forgets an argument, argv[1] might not exist. Check argc and print a usage message:

A calculator that checks its arguments
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int run(int argc, char *argv[]) {
    if (argc != 4) {
        printf("usage: %s <number> <add|mul> <number>\n", argv[0]);
        return 1;
    }
    int a = atoi(argv[1]);
    int b = atoi(argv[3]);
    if (strcmp(argv[2], "add") == 0) {
        printf("%d\n", a + b);
    } else if (strcmp(argv[2], "mul") == 0) {
        printf("%d\n", a * b);
    } else {
        printf("unknown operation: %s\n", argv[2]);
        return 1;
    }
    return 0;
}

int main(void) {
    char *good[] = {"calc", "6", "mul", "7", NULL};
    char *short_one[] = {"calc", "6", NULL};
    char *bad_op[] = {"calc", "6", "pow", "7", NULL};
    run(4, good);
    run(2, short_one);
    run(4, bad_op);
    return 0;
}
output
42
usage: calc <number> <add|mul> <number>
unknown operation: pow

Run and edit it in the app.

Notice strcmp to compare strings — argv[2] == "add" compares addresses, not text, and is almost always false.

Watch it

Looping over all the arguments

Predict: what does it print?
#include <stdio.h>
#include <stdlib.h>

int run(int argc, char *argv[]) {
    int total = 0;
    for (int i = 1; i < argc; i++) {
        total += atoi(argv[i]);
    }
    printf("%d numbers, total %d\n", argc - 1, total);
    return 0;
}

int main(void) {
    char *args[] = {"sum", "4", "10", "x", "6", NULL};
    return run(5, args);
}
What does it print? Show the answer
4 numbers, total 20

Run and edit it in the app.

The loop starts at 1, skipping the program name. And atoi("x") is 0, silently — for real input, check with strtol as in Error Handling.

Running it for real

On your own machine:

gcc calc.c -o calc
./calc 6 mul 7
42
./calc "hello world"      # quotes make one argument with a space in it

main returns its status to the terminal: 0 means success, anything else means failure. Scripts check that number.

You run ./copy a.txt b.txt — what is argc?

Common mistake

Reading argv[1] without checking argc. Run the program with no arguments and argv[1] is NULL — passing it to printf("%s") or atoi can crash. Check argc before touching argv.

Think of it like

Ordering at a counter: "Coffee, large, oat milk." The barista (your program) gets the order as separate words, in order — and should ask again if you only said "Coffee".

Key terms

  • Command-line argument — A word typed after the program's name when starting it.
  • argc — How many arguments, including the program name.
  • argv — The arguments, as an array of strings ending in NULL.
  • Usage message — A line telling the user how to run the program correctly.
  • Exit status — The number main returns; 0 means success.

Check yourself

What is argv[0]?

For ./tool 5 7 , what type is argv[1]?

What should a program check before reading argv[2]?