This project has been created as part of the 42 curriculum by srosu.
keywords: Unix logic
skills: Rigor · Algorithms & AI
ft_printf is a project from the 42 curriculum. The objective is to recreate a simplified version of the standard printf function in C, handling formatted output through variadic arguments and low-level write operations.
The project enforces a deep understanding of:
- Variadic functions using
<stdarg.h> - Format string parsing and specifier dispatching
- Base conversion for integers, hexadecimals, and pointers
- Low-level output using the
writesyscall
The function must handle the following format specifiers: %c, %s, %p, %d, %i, %u, %x, %X, %%.
A variadic function accepts a variable number of arguments. In C, this is done through the <stdarg.h> macros: va_list declares the argument list, va_start initializes it, va_arg retrieves the next argument with a given type, and va_end cleans up. Since printf doesn't know at compile time how many arguments it will receive, understanding how these macros work under the hood is central to the project.
The format string is scanned character by character. Regular characters are written directly to output. When a % is encountered, the next character determines which conversion to apply. This dispatch logic is the core of the implementation and must handle every specified conversion correctly, including edge cases like %% and NULL pointers passed to %s.
Printing integers in different bases (decimal, hexadecimal, octal) requires converting a number digit by digit using modulo and division. For %x and %X, the result is expressed in base 16 with lowercase or uppercase letters respectively. For %p, the pointer address is cast to an unsigned long and printed in hexadecimal with a 0x prefix.
Like the original printf, ft_printf returns the total number of characters printed. This requires tracking every single write call and accumulating the byte count throughout the entire execution, including across all helper functions.
The main function scans the format string one character at a time. When it encounters a %, it reads the next character and routes execution to the corresponding handler. Every other character is printed as-is. The return value accumulates across all output operations.
ft_printf(const char *format, ...)
The entry point. Initializes the va_list, iterates over the format string, and dispatches to the appropriate handler for each specifier. Returns the total character count.
type_is(char c, va_list args)
The dispatcher. Takes the specifier character and the argument list, calls the correct output function, and returns the number of characters printed.
ft_putchar_fd(char c, int fd)
Writes a single character to the given file descriptor using write.
ft_putstr_fd(char *s, int fd)
Writes a string to the given file descriptor. Handles NULL input by printing (null).
ft_putnbr_fd(int n, int fd)
Prints a signed integer. Handles INT_MIN explicitly to avoid undefined behavior on negation.
ft_putnbr_unsigned_fd(unsigned int n, int fd)
Prints an unsigned integer without sign handling.
ft_putnbr_base(unsigned long n, char *base, int fd)
Converts and prints a number in an arbitrary base. Used for %x, %X, and %p.
.
├── ft_printf.c # Main function and parsing loop
├── type_is.c # Specifier dispatcher
├── ft_putchar_fd.c # Character output
├── ft_putstr_fd.c # String output
├── ft_putnbr_fd.c # Signed integer output
├── ft_putnbr_unsigned_fd.c # Unsigned integer output
├── ft_putnbr_base.c # Base conversion output
└── ft_printf.h # Header and prototypes
git clone git@github.com:JojoShaman/printf42.git
cd printf42makeThis produces ft_printf.a.
cc -Wall -Wextra -Werror main.c ft_printf.a -o programft_printf("Hello, %s! You are %d years old.\n", "Alice", 30);
ft_printf("Pointer: %p\n", ptr);
ft_printf("Hex: %x / %X\n", 255, 255);| Rule | Effect |
|---|---|
make |
Compiles all sources and produces ft_printf.a |
make clean |
Removes all .o object files |
make fclean |
Removes .o files and ft_printf.a |
make re |
Full rebuild (fclean + make) |
NULLpassed to%sprints(null)INT_MINhandled correctly in%dand%i%pwith a null pointer prints(nil)%%prints a literal percent sign- Return value accurately reflects the total number of characters written
man 3 printf— behavior of the original function, specifier definitions, and return value semanticsman 2 write— low-level output syscall used throughout the implementationman 0 stdarg.h— variadic argument macros:va_list,va_start,va_arg,va_end
- GeeksforGeeks — Variadic functions in C: covers how
va_argretrieves arguments at runtime - 42 student write-ups — walkthroughs of the parse → dispatch → convert pattern that underpins the implementation
- printf-tester by Tripouille and pft — community testers used to validate behavior across all specifiers and edge cases
- Behavior was also validated manually by comparing output directly against the original
printf
AI tools such as Claude were used as supplementary resources to clarify certain concepts, assist with debugging, and help with documentation.
All implementations and design choices were carried out independently.