A simple, single-header argument parser for C that eliminates boilerplate and code duplication.
- Single header file: Just include
easyargs.hand you're good to go - Zero duplication: Define your arguments once to get struct fields, parsing, and help generation automatically
- Type-safe: Supports all common C types with built-in parsing
- Flexible: Handle required arguments, optional arguments with defaults, and boolean flags
- Automatic help generation: Professional-looking usage and help text generated from your definitions
Check out ./examples to see some use cases!
// Define required positional arguments
#define REQUIRED_ARGS \
REQUIRED_STRING_ARG(input_file, "input", "Input file path") \
REQUIRED_STRING_ARG(output_file, "output", "Output file path")
// Define optional arguments with defaults
#define OPTIONAL_ARGS \
OPTIONAL_UINT_ARG(threads, 1, "-t", "threads", "Number of threads to use")
// Define boolean flags
#define BOOLEAN_ARGS \
BOOLEAN_ARG(help, "-h", "Show help")#include "easyargs.h"int main(int argc, char* argv[]) {
// Initialize with the default values specified above
args_t args = make_default_args();
// Parse arguments
if (!parse_args(argc, argv, &args) || args.help) {
print_help(argv[0]);
return 1;
}
// Use your arguments
printf("Processing %s -> %s\n", args.input_file, args.output_file);
printf("Using %u threads\n", args.threads);
return 0;
}gcc file_processor.c -o file_processor
./file_processor input.txt output.txt -t 4Required arguments are positional and must be provided in order:
#define REQUIRED_ARGS \
REQUIRED_STRING_ARG(name, "label", "description") \
REQUIRED_SIZE_ARG(count, "count", "Number of items") \
REQUIRED_DOUBLE_ARG(threshold, "threshold", "Processing threshold")Supported types:
REQUIRED_STRING_ARG-char*REQUIRED_CHAR_ARG-charREQUIRED_INT_ARG-intREQUIRED_UINT_ARG-unsigned intREQUIRED_LONG_ARG-longREQUIRED_ULONG_ARG-unsigned longREQUIRED_LONG_LONG_ARG-long longREQUIRED_ULONG_LONG_ARG-unsigned long longREQUIRED_SIZE_ARG-size_tREQUIRED_FLOAT_ARG-floatREQUIRED_DOUBLE_ARG-double
Optional arguments have flags and default values:
#define OPTIONAL_ARGS \
OPTIONAL_INT_ARG(verbose, 0, "-v", "level", "Verbosity level") \
OPTIONAL_STRING_ARG(config, "config.ini", "--config", "file", "Configuration file") \
OPTIONAL_DOUBLE_ARG(factor, 1.5, "-f", "factor", "Scaling factor", 2)Note: OPTIONAL_FLOAT_ARG and OPTIONAL_DOUBLE_ARG take an additional precision parameter for displaying defaults in help text.
Supported types: Same as required arguments, but with OPTIONAL_ prefix.
Boolean flags toggle between true and false if present or missing, respectively:
#define BOOLEAN_ARGS \
BOOLEAN_ARG(verbose, "-v", "Enable verbose output") \
BOOLEAN_ARG(quiet, "-q", "Suppress all output") \
BOOLEAN_ARG(force, "--force", "Force overwrite existing files")For basic types, parsing is handled automatically. For required arguments that need custom parsing, you can specify a parser function:
#define REQUIRED_ARG(type, name, label, description, parser)parse_args() returns 0 if parsing fails (e.g., not enough required arguments). Always check the return value:
if (!parse_args(argc, argv, &args)) {
fprintf(stderr, "Error parsing arguments\n");
print_help(argv[0]);
return 1;
}- Download
easyargs.h - Place it in your project directory or include path
- Include it in your source files:
#include "easyargs.h"
No compilation or linking required — it's header-only!
