Clargs is a lightweight, flexible, and powerful C programming language header-only library for parsing command-line arguments. It supports a wide variety of argument types, including flags, strings, characters, integers, floats, doubles, and more. It is designed to make building command-line tools in C easier, safer, and more robust.
-
Supports multiple argument types
- Boolean flags (
-f,--flag) - Strings (
char *) - Character (
char) - Short, Int, Long, Long Long (
short,int,long,long long) - Unsigned variants (
unsigned char,unsigned short,unsigned int,unsigned long,unsigned long long) - Size (
size_t) - Floating-point (
float,double) - Positional arguments
- Boolean flags (
-
Default values for all argument types
-
Required and optional arguments support
-
Automatic help message generation (
-h/--help) -
Short and long options (
-xand--example) -
Easy retrieval of parsed values through getter functions
-
Lightweight and portable — no external dependencies
-
Dynamic argument array growth for flexible usage
- Recommended: Place
clargs.hin the same directory as your.csource file.
#include "clargs.h"-
This works on Linux, Windows, and macOS without any extra setup.
-
For larger projects, you can place it in a dedicated
include/folder and adjust the include path, but for most users, keeping it in the same directory is easiest and safest.
Clargs *cl_create(const char *prog, const char *desc);-
prog: Program name (e.g.,
"myprogram"). -
desc: Description of the program (
shown in help). -
Returns a pointer to a
Clargsparser object.
Example:
Clargs *args = cl_create("myprog", "This is a sample parser");- Flag (boolean)
int cl_add_flag(Clargs *p, char short_name, const char *long_name, const char *help);-
short_name:
-f -
long_name:
--flag -
help: Description
-
Required: Flags are optional (presence = 1, absence = 0)
Example:
cl_add_flag(args, 'v', "verbose", "Enable verbose output");
// Use: ./myprog -v- String
int cl_add_string(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, const char *def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_string(args, 'n', "name", "NAME", "User name", 1, NULL); // Required
cl_add_string(args, 'c', "city", "CITY", "User city", 0, "Unknown"); // Optional- Char
int cl_add_char(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, char def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_char(args, 'g', "gender", "GENDER", "User gender", 0, 'U'); // Optional- Short
int cl_add_short(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, short def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_short(args, 's', "score", "SCORE", "User score", 0, 10);- Int
int cl_add_int(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, int def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_int(args, 'i', "iterations", "N", "Number of iterations", 0, 100);
cl_add_int(args, 0, "count", "COUNT", "Count of items", 1, 0); // Required- Long
int cl_add_long(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, long def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_long(args, 0, "timeout", "TIMEOUT", "Timeout in ms", 0, 5000);- Long long
int cl_add_llong(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, long long def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_llong(args, 0, "bigval", "BIGVAL", "Large integer value", 0, 1234567890123LL);- Size_t
int cl_add_size(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, size_t def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_size(args, 0, "bufsize", "SIZE", "Buffer size", 0, 1024);- Float
int cl_add_float(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, float def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_float(args, 0, "ratio", "RATIO", "Scaling ratio", 0, 1.5f);- Double
int cl_add_double(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, double def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_double(args, 0, "threshold", "THRESH", "Double value", 0, 0.123);- Unsigned Char
int cl_add_uchar(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, unsigned char def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_uchar(args, 'u', "usergender", "UCHAR", "User gender code", 0, 1);- Unsigned Short
int cl_add_ushort(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, unsigned short def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_ushort(args, 0, "portnum", "PORT", "Port number", 0, 8080);- Unsigned Int
int cl_add_uint(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, unsigned int def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_uint(args, 's', "buffersize", "SIZE", "Buffer size", 0, 1024);- Unsigned Long
int cl_add_ulong(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, unsigned long def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_ulong(args, 0, "maxbytes", "MAXBYTES", "Maximum bytes allowed", 0, 500000UL);- Unsigned Long Long
int cl_add_ullong(Clargs *p, char short_name, const char *long_name, const char *meta, const char *help, int req, unsigned long long def);-
short_name: Corresponds to a single-dash option like-n. Pass0if not needed. -
long_name: Corresponds to a double-dash option like--number. Pass0if not needed. -
meta is the place-holder name shown in usage (e.g.,
--name NAME). -
help: The help message describing the option. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional,
def(default) is used if missing -
def: The default value for the argument.- For strings: pass
NULLif no default is needed. - For numeric types: pass
0if no default is needed. - For
char: pass'\0'if no default is needed.
- For strings: pass
Example:
cl_add_ullong(args, 0, "hugeval", "HUGEVAL", "Very large integer value", 0, 123456789012345ULL);- Positional Arguments
int cl_add_pos(Clargs *p, const char *name, const char *help, int req);-
name: The name of the positional argument. This will be used to identify it. -
help: The help message describing the positional argument. PassNULLif not needed. -
req(required) = 1 → User must provide
-
req(required) = 0 → Optional
Example:
cl_add_pos(args, "input", "Input filename", 1); // Required positional argument
cl_add_pos(args, "output", "Output filename", 0); // Optional positionalint cl_parse(Clargs *p, int argc, char **argv);-
Parses
argc/argv. -
Returns
0on success,-1on error. -
Automatically checks required arguments.
Example:
if (cl_parse(args, argc, argv) != 0) {
fprintf(stderr, "Error parsing arguments\n");
return 1;
}All getters except cl_get_flag and cl_get_string optionally provide a pointer to ok to check if value exists.
int ok;
const char *name = cl_get_string(args, "name");
int iter = cl_get_int(args, "iterations", &ok);
if(ok) printf("Iterations = %d\n", iter);| Function | Returns | Example |
|---|---|---|
| cl_get_flag | int (0/1) | cl_get_flag(args, "verbose"); |
| cl_get_string | const char * | cl_get_string(args, "name"); |
| cl_get_char | char | cl_get_char(args, "gender", &ok); |
| cl_get_short | short | cl_get_short(args, "score", &ok); |
| cl_get_int | int | cl_get_int(args, "count", &ok); |
| cl_get_long | long | cl_get_long(args, "timeout", &ok); |
| cl_get_llong | long long | cl_get_llong(args, "bigval", &ok); |
| cl_get_uchar | unsigned char | cl_get_uchar(args, "level", &ok); |
| cl_get_ushort | unsigned short | cl_get_ushort(args, "port", &ok); |
| cl_get_uint | unsigned int | cl_get_uint(args, "size", &ok); |
| cl_get_ulong | unsigned long | cl_get_ulong(args, "maxval", &ok); |
| cl_get_ullong | unsigned long long | cl_get_ullong(args, "hugeval", &ok); |
| cl_get_size | size_t | cl_get_size(args, "bufsize", &ok); |
| cl_get_float | float | cl_get_float(args, "ratio", &ok); |
| cl_get_double | double | cl_get_double(args, "pi", &ok); |
void cl_help(Clargs *p);-
Automatically prints usage and description.
-
Includes all arguments, defaults, and required info.
Example:
cl_help(args);void cl_free(Clargs *p);- Frees memory used by parser.
Example:
cl_free(args);/*
Example program using clargs.h
--------------------------------
- Shows how to add every argument type
- Shows how to get values back
- Uses &ok to check if argument is registered
- Remember: use 1 for required, 0 for optional
- You can pass 0 for short_name or long_name if you don't need them
*/
#include <stdio.h>
#include "clargs.h"
int main(int argc, char **argv) {
int ok;
// Create parser
Clargs *args = cl_create("example", "Demo of all clargs functions");
// Add different argument types
cl_add_flag(args, 'v', "verbose", "Enable verbose mode"); // flag
cl_add_string(args, 'n', "name", "NAME", "User name", 0, "guest"); // string
cl_add_char(args, 0, "gender", "GENDER", "Gender (M/F)", 0, 'U'); // char
cl_add_short(args, 's', "score", "SCORE", "Short number", 0, 10); // short
cl_add_int(args, 'p', "port", "PORT", "Port number", 0, 8080); // int
cl_add_long(args, 0, "timeout", "TIMEOUT", "Timeout in ms", 0, 5000L); // long
cl_add_llong(args, 0, "bigval", "BIGVAL", "Big 64-bit number", 0, 123456789LL); // long long
cl_add_uchar(args, 0, "ubyte", "UBYTE", "Unsigned char", 0, 255); // unsigned char
cl_add_ushort(args, 0, "u16", "U16", "Unsigned short", 0, 65000); // unsigned short
cl_add_uint(args, 0, "u32", "U32", "Unsigned int", 0, 123456789u); // unsigned int
cl_add_ulong(args, 0, "ulong", "ULONG", "Unsigned long", 0, 1234567890UL);// unsigned long
cl_add_ullong(args, 0, "ull", "ULLONG", "Unsigned long long", 0, 1234567890123ULL); // unsigned long long
cl_add_size(args, 0, "bufsize", "SIZE", "Buffer size", 0, 4096); // size_t
cl_add_float(args, 0, "ratio", "RATIO", "Float value", 0, 0.75f); // float
cl_add_double(args, 0, "threshold", "THRESH", "Double value", 0, 0.123); // double
cl_add_pos(args, "input", "Input file", 1); // positional (required)
// Parse command-line
if (cl_parse(args, argc, argv) != 0) {
cl_free(args);
return 1;
}
// Get values back
printf("verbose : %d\n", cl_get_flag(args, "verbose"));
printf("name : %s\n", cl_get_string(args, "name"));
char gender = cl_get_char(args, "gender", &ok);
if (ok) printf("gender : %c\n", gender);
short score = cl_get_short(args, "score", &ok);
if (ok) printf("score : %d\n", score);
int port = cl_get_int(args, "port", &ok);
if (ok) printf("port : %d\n", port);
long timeout = cl_get_long(args, "timeout", &ok);
if (ok) printf("timeout : %ld\n", timeout);
long long bigval = cl_get_llong(args, "bigval", &ok);
if (ok) printf("bigval : %lld\n", bigval);
unsigned char ubyte = cl_get_uchar(args, "ubyte", &ok);
if (ok) printf("ubyte : %u\n", ubyte);
unsigned short u16 = cl_get_ushort(args, "u16", &ok);
if (ok) printf("u16 : %u\n", u16);
unsigned int u32 = cl_get_uint(args, "u32", &ok);
if (ok) printf("u32 : %u\n", u32);
unsigned long ul = cl_get_ulong(args, "ulong", &ok);
if (ok) printf("ulong : %lu\n", ul);
unsigned long long ull = cl_get_ullong(args, "ull", &ok);
if (ok) printf("ull : %llu\n", ull);
size_t bufsize = cl_get_size(args, "bufsize", &ok);
if (ok) printf("bufsize : %zu\n", bufsize);
float ratio = cl_get_float(args, "ratio", &ok);
if (ok) printf("ratio : %f\n", ratio);
double thresh = cl_get_double(args, "threshold", &ok);
if (ok) printf("threshold : %f\n", thresh);
printf("input : %s\n", cl_get_string(args, "input"));
// Free parser
cl_free(args);
return 0;
}This project is licensed under the MIT License