Command Line Flags in C

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

void print_usage() {
    printf("Usage of ./command-line-flags:\n");
    printf("  -word string\n        a string (default \"foo\")\n");
    printf("  -numb int\n        an int (default 42)\n");
    printf("  -fork\n        a bool\n");
    printf("  -svar string\n        a string var (default \"bar\")\n");
}

int main(int argc, char *argv[]) {
    char *word = "foo";
    int numb = 42;
    bool fork = false;
    char *svar = "bar";

    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-word") == 0 && i + 1 < argc) {
            word = argv[++i];
        } else if (strcmp(argv[i], "-numb") == 0 && i + 1 < argc) {
            numb = atoi(argv[++i]);
        } else if (strcmp(argv[i], "-fork") == 0) {
            fork = true;
        } else if (strcmp(argv[i], "-svar") == 0 && i + 1 < argc) {
            svar = argv[++i];
        } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            print_usage();
            return 0;
        } else if (argv[i][0] == '-') {
            printf("flag provided but not defined: %s\n", argv[i]);
            print_usage();
            return 1;
        } else {
            break;
        }
    }

    printf("word: %s\n", word);
    printf("numb: %d\n", numb);
    printf("fork: %s\n", fork ? "true" : "false");
    printf("svar: %s\n", svar);
    
    printf("tail:");
    for (int i = argc - 1; i >= 1 && argv[i][0] != '-'; i--) {
        printf(" %s", argv[i]);
    }
    printf("\n");

    return 0;
}

Command-line flags are a common way to specify options for command-line programs. For example, in wc -l the -l is a command-line flag.

In C, we don’t have a built-in flag parsing package like Go’s flag package. Instead, we’ll implement basic command-line flag parsing manually using the argc and argv parameters of the main function.

We declare variables for each flag with default values. Then, we iterate through the command-line arguments to parse the flags and update the variables accordingly.

The program supports the following flags:

  • -word: a string flag with default value “foo”
  • -numb: an integer flag with default value 42
  • -fork: a boolean flag
  • -svar: a string flag with default value “bar”

We also implement a basic help text functionality with -h or --help flags.

To compile and run the program:

$ gcc -o command-line-flags command-line-flags.c
$ ./command-line-flags -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
fork: true
svar: flag
tail:

Note that if you omit flags, they automatically take their default values:

$ ./command-line-flags -word=opt
word: opt
numb: 42
fork: false
svar: bar
tail:

Trailing positional arguments can be provided after any flags:

$ ./command-line-flags -word=opt a1 a2 a3
word: opt
numb: 42
fork: false
svar: bar
tail: a3 a2 a1

Use -h or --help flags to get the help text for the command-line program:

$ ./command-line-flags -h
Usage of ./command-line-flags:
  -word string
        a string (default "foo")
  -numb int
        an int (default 42)
  -fork
        a bool
  -svar string
        a string var (default "bar")

If you provide a flag that wasn’t specified, the program will print an error message and show the help text:

$ ./command-line-flags -wat
flag provided but not defined: -wat
Usage of ./command-line-flags:
...

This C implementation provides similar functionality to the original example, with basic command-line flag parsing and usage information.