A tiny, header-only C library that provides explicit format-argument binding for standard printf using preprocessor tuples.
Instead of writing a single, detached format string followed by a separate list of arguments, ezprintf allows you to associate format specifiers directly with their corresponding values using short, type-aware macros (like _i32(10) or _x16("04", 123)).
In standard C, keeping a long printf format string in sync with its arguments is error-prone and hard to read, especially when dealing with fixed-width integers and PRI* macros from <inttypes.h>.
Standard way:
printf("Values: %" PRIu8 " %0*" PRIx32 "\n", 255, 8, 0xdead);With ezprintf:
ezprintf("Values: ", _u8(255), " ", _x32("0*", 8, 0xdead), "\n");It makes it immediately clear which format belongs to which argument.
At compile time, ezprintf processes the arguments as preprocessor tuples:
- Bare string literals (like
"text") are automatically wrapped into tuples. - The
MAPmacro separates all format fragments from their arguments. - String literal concatenation merges all format fragments into a single string.
- The remaining arguments are unpacked and passed directly into a standard
printfcall.
#include <stdio.h>
#include "ezprintf.h"
int main(void) {
// 1. Explicit binding for fixed-width types
ezprintf("test ", _i32(10), "\n");
// Expands to: printf("test %" PRId32 "\n", 10);
// 2. Handling custom formatting flags (width and padding)
ezprintf(_x16("04", 123), "\n");
// Expands to: printf("%04" PRIx16 "\n", 123);
// 3. Mixing with standard printf tuple syntax if needed
ezprintf(("Hello, %s!\n", "world"));
// Expands to: printf("Hello, %s!\n", "world");
return 0;
}The library provides wrappers for all standard PRI* macros from <inttypes.h> for signed/unsigned decimals, octals, hexadecimals, fast/least types, and pointers:
_d8(...)to_d64(...),_dPTR(...),_dMAX(...)_i8(...)to_i64(...),_iPTR(...),_iMAX(...)_u8(...)to_u64(...),_uPTR(...),_uMAX(...)_x8(...)to_x64(...),_xPTR(...),_xMAX(...)_X8(...)to_X64(...),_XPTR(...),_XMAX(...)_o8(...)to_o64(...),_oPTR(...),_oMAX(...)
- C99 or later (requires variadic macros).
- GCC or Clang (relies on the GNU extension
, ##__VA_ARGS__for empty argument elimination). - map-macro.h by William R. Swanson (included in the repository).
This is free and unencumbered software released into the public domain. For details, see the header or UNLICENSE.