ft_printf
ft_printf
The goal of this project is to recode the standard printf function from libc. This implementation handles various format specifiers and provides a foundational library tool that can be integrated into other C projects.
Project Requirements
- Supported Conversions:
%c,%s,%p,%d,%i,%u,%x,%X, and%%. - Variadic Arguments: Efficient use of
stdarg.hto handle an unknown number of parameters. - Library Integration: Designed to be compiled into a
libftprintf.alibrary. - Stability: Robust handling of edge cases, such as
NULLstrings and0pointers.
Implementation Highlights
1. The Dispatcher (Checker)
The core logic resides in a “checker” function that identifies the format specifier and routes it to the appropriate specialized output function.
static int checker(const char toCheck, va_list args)
{
if (toCheck == 'c')
return (ft_putchar(va_arg(args, int)));
else if (toCheck == 'u')
return (ft_putnbr(va_arg(args, unsigned int)));
else if ((toCheck == 'i') || (toCheck == 'd'))
return (ft_putnbr(va_arg(args, int)));
else if (toCheck == 's')
return (ft_putstr(va_arg(args, char *)));
else if (toCheck == 'x' || toCheck == 'X')
return (ft_put_hex(va_arg(args, unsigned int), toCheck));
else if (toCheck == 'p')
return (ft_put_ptr(va_arg(args, void *)));
else if (toCheck == '%')
return (ft_putchar('%'));
return (-1);
}
2. Recursive Hexadecimal Conversion
To handle hexadecimal conversions (%x, %X) and pointer addresses (%p), I implemented recursive functions that peel off digits using base-16 math.
static void put_hexa(unsigned int nbr, char up)
{
static char upper_digits[] = "0123456789ABCDEF";
static char lower_digits[] = "0123456789abcdef";
if (nbr >= 16)
put_hexa((nbr / 16), up); // Recursive call
if (up == 'X')
write(1, &upper_digits[nbr % 16], 1);
else
write(1, &lower_digits[nbr % 16], 1);
}
3. Pointer Address Handling
The %p implementation includes the 0x prefix and correctly handles nil addresses, matching the behavior of the standard library.
int ft_put_ptr(void *addr)
{
if (addr == 0)
return (write(1, "(nil)", 5)); // Standard libc behavior
write(1, "0x", 2);
put_ptr((unsigned long long)addr);
return (ptr_digits((unsigned long long)addr) + 2);
}
Usage
1. Compilation
Build the library using the provided Makefile:
make
2. Integration
Include the header in your C file and compile with the library:
#include "ft_printf.h"
int main()
{
ft_printf("Hello %s, the hex value is %x\n", "World", 42);
return (0);
}
Skills Learned
- Variadic Functions: Mastering
va_list,va_start,va_arg, andva_end. - Data Representation: Converting integers and long addresses into strings and hexadecimal formats.
- Recursion: Using recursive logic for clean number formatting.
- Modular Design: Organizing a project into specialized files for better maintainability.
Author
- GitHub: cuteKittenArri