C Basics: Validate Argument Count Before Reading Values
A small command-line tool can reject an unexpected call before reading argument values. This program accepts exactly one label and never invokes another command.
Prepare a scratch directory
Tested on Linux amd64 with GCC 14.2.0. Install GCC and make gcc available on PATH. You also need Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. This example uses the C standard library.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as command-line-arguments-demo.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argument_count, char *arguments[]) {
if (argument_count != 3 || strcmp(arguments[1], "--label") != 0 ||
arguments[2][0] == '\0') {
fputs("Usage: command-line-arguments-demo --label TEXT\n", stderr);
return EXIT_FAILURE;
}
printf("Label: [%s]\n", arguments[2]);
printf("Value arguments: %d\n", argument_count - 2);
printf("Sentinel is null: %d\n", arguments[argument_count] == NULL);
return EXIT_SUCCESS;
}Compile and run it. The second command runs only after compilation succeeds:
gcc -std=c17 -Wall -Wextra -Werror -pedantic command-line-arguments-demo.c -o command-line-arguments-demo &&
./command-line-arguments-demo --label 'two words; not a command'Observed output:
Label: [two words; not a command]
Value arguments: 1
Sentinel is null: 1Read the result
The count check is evaluated first. Short-circuit evaluation prevents reading arguments[1] or arguments[2] when too few arguments were supplied. Shell quoting passes the spaces and semicolon as one value; printf prints the value as data. The entry after the final argument is a null pointer.
Apply it carefully
The shell removes quotes before starting the program, so unquoted metacharacters could be interpreted before this C code runs. Quoting the invocation and avoiding system or shell command construction solve different problems. This deliberately small parser rejects extra options and empty labels; it is not a general option parser.
The official reference documents the behavior used here.
Clean up
Remove only the source and executable created for this example, then return to the starting directory:
rm -- command-line-arguments-demo.c command-line-arguments-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.