hero-image

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.h to handle an unknown number of parameters.
  • Library Integration: Designed to be compiled into a libftprintf.a library.
  • Stability: Robust handling of edge cases, such as NULL strings and 0 pointers.

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, and va_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

arri