BaseMax / c-argparse
A lightweight, portable CLI argument parsing library for C programs. A reusable and lightweight CLI argument parsing library for C programs. C (C99/C11), portable ANSI C, no external dependencies.
README
c-argparse
A lightweight, portable CLI argument parsing library for C programs.
Features
- Simple API - Easy to use with minimal boilerplate
- Flags - Boolean options (e.g.,
-v,--verbose) - Options with values - String, integer, and float options (e.g.,
-o file,--output=file) - Positional arguments - Support for non-option arguments
- Default values - Set default values for options
- Automatic help generation - Built-in
--helpsupport - Error reporting - Clear error messages for invalid input
- Portable - Works on Linux, macOS, and Windows
- No dependencies - Pure C99, no external libraries required
- Well tested - Comprehensive unit test suite
Quick Start
Building
make all # Build library, examples, and tests
make test # Run unit tests
make clean # Clean build artifacts
Basic Example
#include <stdio.h>
#include "argparse.h"
int main(int argc, const char **argv)
{
int verbose = 0;
const char *output = NULL;
int count = 10; // Default value
const argparse_option options[] = {
ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output"),
ARGPARSE_STRING("o", "output", &output, "Output file path"),
ARGPARSE_INTEGER("n", "count", &count, "Number of iterations"),
ARGPARSE_OPT_END_ENTRY
};
argparse parser;
argparse_init(&parser, options, "A simple example program.", NULL);
int result = argparse_parse(&parser, argc, argv);
if (result < 0) {
if (parser.error) {
argparse_error(&parser);
}
argparse_cleanup(&parser);
return 1;
}
printf("Verbose: %s\n", verbose ? "ON" : "OFF");
printf("Output: %s\n", output ? output : "(none)");
printf("Count: %d\n", count);
argparse_cleanup(&parser);
return 0;
}
API Reference
Data Types
argparse_option_type
Defines the type of a command-line option:
ARGPARSE_OPT_BOOLEAN- Boolean flagARGPARSE_OPT_STRING- String optionARGPARSE_OPT_INTEGER- Integer optionARGPARSE_OPT_FLOAT- Float optionARGPARSE_OPT_POSITIONAL- Positional argumentARGPARSE_OPT_GROUP- Group header for help textARGPARSE_OPT_END- Sentinel to mark end of options
argparse_option
Structure defining a single command-line option:
typedef struct argparse_option {
argparse_option_type type; // Type of option
const char *short_name; // Short option (e.g., "v" for -v)
const char *long_name; // Long option (e.g., "verbose" for --verbose)
void *value; // Pointer to variable to store value
const char *help; // Help text
int flags; // Option flags
void *default_value; // Default value (optional)
} argparse_option;
argparse
Main parser context structure:
typedef struct argparse {
const char *program_name;
const char *description;
const char *epilog;
const argparse_option *options;
int argc;
const char **argv;
int error;
char error_msg[256];
int positional_count;
const char **positional_args;
// ... internal fields
} argparse;
Functions
argparse_init()
Initialize the argument parser.
void argparse_init(argparse *parser, const argparse_option *options,
const char *description, const char *epilog);
Parameters:
parser- Pointer to parser contextoptions- Array of option definitions (must end withARGPARSE_OPT_END_ENTRY)description- Optional program description for help textepilog- Optional epilog text for help
argparse_parse()
Parse command-line arguments.
int argparse_parse(argparse *parser, int argc, const char **argv);
Parameters:
parser- Pointer to initialized parserargc- Argument count frommain()argv- Argument vector frommain()
Returns:
- Number of positional arguments parsed
-1on error
argparse_help()
Print help message to stdout.
void argparse_help(const argparse *parser);
argparse_error()
Print error message to stderr.
void argparse_error(const argparse *parser);
argparse_cleanup()
Free resources allocated by the parser.
void argparse_cleanup(argparse *parser);
argparse_get_error()
Get the error message if parsing failed.
const char *argparse_get_error(const argparse *parser);
Returns:
- Error message string, or
NULLif no error
Helper Macros
ARGPARSE_BOOLEAN()
Define a boolean flag option.
ARGPARSE_BOOLEAN(short_opt, long_opt, var, help_text)
Example:
ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output")
ARGPARSE_STRING()
Define a string option.
ARGPARSE_STRING(short_opt, long_opt, var, help_text)
Example:
ARGPARSE_STRING("o", "output", &output, "Output file path")
ARGPARSE_INTEGER()
Define an integer option.
ARGPARSE_INTEGER(short_opt, long_opt, var, help_text)
Example:
ARGPARSE_INTEGER("n", "count", &count, "Number of iterations")
ARGPARSE_GROUP()
Define a group header for organizing help text.
ARGPARSE_GROUP(help_text)
Example:
ARGPARSE_GROUP("File Options")
ARGPARSE_OPT_END_ENTRY
Sentinel to mark the end of the options array.
const argparse_option options[] = {
ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Verbose output"),
ARGPARSE_OPT_END_ENTRY
};
Usage Examples
Flags
int verbose = 0;
int debug = 0;
const argparse_option options[] = {
ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output"),
ARGPARSE_BOOLEAN("d", "debug", &debug, "Enable debug mode"),
ARGPARSE_OPT_END_ENTRY
};
Usage:
./program -v -d
./program --verbose --debug
./program -vd # Combined short flags
Options with Values
const char *output = NULL;
int threads = 4; // Default value
float rate = 1.0f;
const argparse_option options[] = {
ARGPARSE_STRING("o", "output", &output, "Output file"),
ARGPARSE_INTEGER("j", "threads", &threads, "Number of threads"),
{ARGPARSE_OPT_FLOAT, "r", "rate", &rate, "Processing rate", ARGPARSE_OPT_NONE, NULL},
ARGPARSE_OPT_END_ENTRY
};
Usage:
./program -o output.txt -j 8 -r 2.5
./program --output=output.txt --threads=8 --rate=2.5
./program -ooutput.txt -j8 # Immediate value for short options
Positional Arguments
argparse parser;
argparse_init(&parser, options, NULL, NULL);
int result = argparse_parse(&parser, argc, argv);
if (result > 0) {
printf("Positional arguments:\n");
for (int i = 0; i < result; i++) {
printf(" %s\n", parser.positional_args[i]);
}
}
Usage:
./program file1.txt file2.txt file3.txt
./program -v --output=out.txt input1.txt input2.txt
Default Values
int count = 10; // Will be used if not specified
const char *format = "json";
int default_count = 10;
const char *default_format = "json";
const argparse_option options[] = {
{ARGPARSE_OPT_INTEGER, "n", "count", &count, "Count", ARGPARSE_OPT_NONE, &default_count},
{ARGPARSE_OPT_STRING, "f", "format", &format, "Format", ARGPARSE_OPT_NONE, &default_format},
ARGPARSE_OPT_END_ENTRY
};
Grouped Options (Help Organization)
const argparse_option options[] = {
ARGPARSE_GROUP("General Options"),
ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Verbose output"),
ARGPARSE_BOOLEAN("q", "quiet", &quiet, "Quiet mode"),
ARGPARSE_GROUP("File Options"),
ARGPARSE_STRING("i", "input", &input, "Input file"),
ARGPARSE_STRING("o", "output", &output, "Output file"),
ARGPARSE_OPT_END_ENTRY
};
Error Handling
argparse parser;
argparse_init(&parser, options, "My program", NULL);
int result = argparse_parse(&parser, argc, argv);
if (result < 0) {
if (parser.error) {
argparse_error(&parser); // Prints error to stderr
}
argparse_cleanup(&parser);
return 1;
}
// Use parsed values...
argparse_cleanup(&parser);
Examples
The repository includes two complete example programs:
Basic Example (examples/basic.c)
Demonstrates all core features:
- Boolean flags
- String, integer, and float options
- Positional arguments
- Help generation
Build and run:
make examples
./build/basic --help
./build/basic -v -d -o output.txt -i input.txt -n 20 file1.txt file2.txt
Advanced Example (examples/advanced.c)
Shows more complex usage:
- Grouped options
- Default values
- Input validation
- File processing simulation
Build and run:
make examples
./build/advanced --help
./build/advanced -v --format=xml -j 8 input1.txt input2.txt
Testing
The library includes a comprehensive test suite:
make test
Tests cover:
- Flag parsing (short and long)
- Combined short flags
- String, integer, and float options
- Positional arguments
- Mixed options and positional args
- Error handling
- Default values
- Edge cases
Platform Support
This library is designed to be portable and works on:
- Linux - Tested with GCC
- macOS - Compatible with Clang
- Windows - Works with MinGW/MSYS2
The library uses only standard C99 features and has no external dependencies.
Design Philosophy
- Simplicity - Minimal API surface, easy to learn
- Portability - Standard C99, works everywhere
- Zero dependencies - No external libraries required
- Type safety - Type-safe option definitions
- Memory safety - Proper cleanup and error handling
- User-friendly - Clear error messages and automatic help
Building and Installation
Prerequisites
- C compiler supporting C99 (GCC, Clang, MSVC, MinGW)
- Make (optional, for using the Makefile)
Building
# Build everything
make all
# Build only examples
make examples
# Build only tests
make tests
# Clean build artifacts
make clean
Manual Building
You can also build manually without Make:
# Compile the library
gcc -c -std=c99 -I./include src/argparse.c -o argparse.o
# Compile your program
gcc -std=c99 -I./include your_program.c argparse.o -o your_program
Integration
To use in your project:
- Copy
include/argparse.handsrc/argparse.cto your project - Include
argparse.hin your source files - Compile
argparse.cwith your project
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
Author
Max Base - GitHub
KiloClaw - Managed 🦀 