Skip to content
Laviyx Learn

Try

C course menu

Command-Line Arguments in C: argc and argv

Learn to read command-line arguments in C with argc and argv: what argv[0] holds, looping over arguments, converting arguments to numbers safely with strtol, handling options and flags, printing usage messages, and returning exit codes.

Advanced7 min readUpdated
On this page

Command-line tools such as gcc, git and ls take their input from the words typed after the program name. A C program receives those words through two parameters of main.

argc and argv#

C
int main(int argc, char *argv[])
  • argc (argument count) is the number of words, including the program name.
  • argv (argument vector) is an array of strings: argv[0] is usually the program's name, argv[1] to argv[argc - 1] are the arguments, and argv[argc] is NULL.

char *argv[] and char **argv mean the same thing.

Printing the arguments#

Running ./args report.txt -v 42:

C
#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("argc = %d\n", argc);
    for (int i = 1; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}
Output
argc = 4
argv[1] = report.txt
argv[2] = -v
argv[3] = 42

The loop starts at 1 to skip the program name, whose exact form depends on how the program was started. The shell splits arguments at spaces; quote an argument to keep spaces in it: ./args "my file.txt".

Converting arguments to numbers#

Arguments are always strings. Convert them with strtol or strtod and check that the whole argument was a valid number:

Running ./sum 10 20 abc 5:

C
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    long total = 0;
    int skipped = 0;
    for (int i = 1; i < argc; i++) {
        char *end;
        long value = strtol(argv[i], &end, 10);
        if (end == argv[i] || *end != '\0') {
            skipped++;                       /* not a whole number */
            continue;
        }
        total += value;
    }
    printf("total = %ld\n", total);
    if (skipped > 0) fprintf(stderr, "warning: skipped %d invalid argument(s)\n", skipped);
    return 0;
}
Output
total = 35
warning: skipped 1 invalid argument(s)

Error messages go to stderr, so they stay separate from the program's normal output when it is redirected to a file.

Options, usage messages and exit codes#

A good command-line program checks its arguments, prints a usage message when they are wrong, and returns an exit code: 0 (EXIT_SUCCESS) for success and non-zero (EXIT_FAILURE) for failure. Scripts and other programs check this code.

Running ./greet -u --times 2 Asha:

C
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void usage(const char *prog) {
    fprintf(stderr, "usage: %s [-u] [--times N] NAME\n", prog);
}

int main(int argc, char *argv[]) {
    int upper = 0;
    long times = 1;
    const char *name = NULL;

    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-u") == 0) {
            upper = 1;
        } else if (strcmp(argv[i], "--times") == 0 && i + 1 < argc) {
            times = strtol(argv[++i], NULL, 10);
        } else if (argv[i][0] == '-') {
            usage(argv[0]);
            return EXIT_FAILURE;
        } else {
            name = argv[i];
        }
    }
    if (name == NULL || times < 1) {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    for (long t = 0; t < times; t++) {
        printf("Hello, ");
        for (const char *p = name; *p; p++) putchar(upper ? toupper((unsigned char)*p) : *p);
        printf("!\n");
    }
    return EXIT_SUCCESS;
}
Output
Hello, ASHA!
Hello, ASHA!

On Linux and macOS, echo $? shows the last program's exit code; in PowerShell, use $LASTEXITCODE. For complex options, POSIX systems provide the getopt function (in <unistd.h>), which is not part of standard C.

Practice#

Practice exercise

Write a program that expects exactly two arguments, a word and a file-name-like string, and prints whether the second argument ends with the first (for example ./endswith .txt notes.txt). Print a usage message and return EXIT_FAILURE when the argument count is wrong.

Show solution

Running ./endswith .txt notes.txt:

C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "usage: %s SUFFIX TEXT\n", argv[0]);
        return EXIT_FAILURE;
    }
    const char *suffix = argv[1], *text = argv[2];
    size_t ls = strlen(suffix), lt = strlen(text);
    int ends = lt >= ls && strcmp(text + lt - ls, suffix) == 0;
    printf("'%s' %s with '%s'\n", text, ends ? "ends" : "does not end", suffix);
    return EXIT_SUCCESS;
}
Output
'notes.txt' ends with '.txt'

Key takeaway#

Finished this lesson?