This project has been created as part of the 42 curriculum by dporhomo.
The goal of this project is to replicate the behavior of the standard printf function, including handling variable argument lists (va_list).
The project includes both the mandatory and bonus parts. The library compiles into libftprintf.a using the provided Makefile and supports formatting of strings, characters, integers, and hexadecimal numbers, along with flags for padding, alignment, and precision.
%c: Prints a single character.%s: Prints a string.%p: Prints avoid *pointer in hexadecimal format.%d: Prints a decimal (base 10) number.%i: Prints an integer in base 10.%u: Prints an unsigned decimal (base 10) number.%x: Prints a hexadecimal (base 16) number in lowercase.%X: Prints a hexadecimal (base 16) number in UPPERCASE.%%: Prints a percent sign.
-: Left alignment.0: Zero padding..: Precision specifier (digits or string truncation).#: Hexadecimal prefix (0xor0X).(space): Leading blank for positive numbers.+: Leading plus sign for positive numbers.*: Dynamic width or precision via arguments.
- Download the repository.
- Inside the repository directory, compile the
libftprintf.alibrary:
make#include "ft_printf.h"If main.c is located elsewhere:
#include "path/to/ft_printf/ft_printf.h"If main.c is in the repository root:
cc -Wall -Wextra -Werror main.c libftprintf.a -o my_program
./my_programIf main.c is located somewhere else:
cc -Wall -Wextra -Werror main.c path/to/ft_printf/libftprintf.a -o my_program
./my_programTo ensure modularity, readability, and compliance with the Norminette (notably the 4-argument limit), this project uses three custom data structures.
Encapsulates the state of the printf cycle.
-
Purpose: Tracks the current index (
i) of the format string and the total printed character count (count). -
Reasoning: Passing a single pointer (
t_print *tab) allows state modification without exceeding argument limits.
A checklist populated whenever a % conversion is encountered.
-
Purpose: Stores flag states (
-,+,#, etc.) and values (width,precision). -
Reasoning: Cleanly separates parsing from printing. Printer functions simply read the stored flags.
Used for numeric outputs (integers, hex, unsigned). Ensures correct calculation of length, padding, signs, and precision.
typedef struct s_layout
{
int len;
int zeros;
int sign;
} t_layout;-
Purpose: Acts as a “blueprint” describing the number of digits, precision zeros, and required sign.
-
Reasoning: Originally implemented using an integer array to satisfy Norminette limits; later refactored to a struct for clarity. The printer first determines final output length (sign + precision zeros + digits), then prints in the correct order Padding → Sign → Zeros → Digits.
Iterate: Main loop reads the format string.
Parse:
Upon encountering %, ft_parse_format fills a t_flags struct with appropriate flags.
Print:
Printer functions (e.g., ft_print_spec) carries out printing of all formatting specifiers by calling up appropriate disgined subfunctions.
- Standard C Library documentation for
printf. man stdargfor variable argument list macros.
Artificial Intelligence tools (LLMs) were used for the following:
-
Conceptual overview: Clarified edge cases and high-level architecture for the
printfimplementation. -
Testing strategy: Provided an edge-case checklist (e.g.,
INT_MIN, pointer formatting) used in custom tests.
Testing was performed using a custom main.c running 53 tests, covering normal and edge cases.
18 tests (NULL strings, empty strings, dynamic width).
20 tests (INT_MIN/INT_MAX, precision vs width, zero padding).
11 tests (hash flag, alignment, padding combinations).
4 tests (including NULL pointers).