A reimplementation of the C standard printf function — handling format specifiers, variadic arguments, and byte-accurate output.
"This project taught me how variadic functions work at the ABI level — how
va_list,va_start,va_arg, andva_endlet a function accept an unknown number of arguments at runtime. I also learned how format string parsing works character by character, and how to track byte-accurate output counts. These mechanics are present in every logging library, serialization system, and custom output formatter in production code."
Understanding how printf works internally demystifies one of the most commonly used functions in C and C-adjacent languages. It also gives direct insight into how logging frameworks like spdlog, fmt, and Python's str.format are implemented.
A custom ft_printf function that replicates the behavior of the standard printf, supporting:
| Specifier | Output |
|---|---|
%c |
Single character |
%s |
String |
%d / %i |
Signed decimal integer |
%u |
Unsigned decimal integer |
%x |
Hexadecimal (lowercase) |
%X |
Hexadecimal (uppercase) |
%p |
Pointer address |
%% |
Literal percent sign |
Returns the total number of bytes written — exactly like the real printf.
The implementation splits output handling into focused utility files: utils_char.c (characters and strings), utils_int.c (signed and unsigned integers), and utils_hex.c (hexadecimal and pointer formatting). Each file tracks written bytes through a pointer parameter (int *written_bytes), passed down the call chain — a clean alternative to using globals or return value chaining. This design makes the code easy to extend with new specifiers without touching existing logic.
git clone https://github.com/gustavofsousa/ft_printf_42.git
cd ft_printf_42
make#include "ft_printf.h"
int main(void)
{
int num = 42;
char *str = "Hello, 42!";
void *ptr = #
ft_printf("Integer: %d\n", num);
ft_printf("String: %s\n", str);
ft_printf("Hex lower: %x\n", num);
ft_printf("Hex upper: %X\n", num);
ft_printf("Pointer: %p\n", ptr);
ft_printf("Unsigned: %u\n", (unsigned int)num);
ft_printf("Percent: %%\n");
return (0);
}Compile with:
gcc main.c ft_printf.c utils_char.c utils_int.c utils_hex.c -o programft_printf_42/
├── ft_printf.c # Entry point — format string parser
├── ft_printf.h # Header — prototypes and includes
├── utils_char.c # %c and %s handling
├── utils_int.c # %d, %i, %u handling
├── utils_hex.c # %x, %X, %p handling
└── Makefile
- Variadic functions (
stdarg.h—va_list,va_start,va_arg,va_end) - Format string parsing (character-by-character)
- Hexadecimal and pointer representation
- Byte-accurate output tracking
- Modular code design in C
This project was developed as part of the 42 School curriculum.
Made with ☕ at 42 Rio de Janeiro