Skip to content

πŸ–¨οΈ ft_printf (42 Paris) β€” Extensible reimplementation of libc printf in C. Variadic arguments, flags, width, precision and conversions. Dynamic buffering, strict memory management, and modular design.

Notifications You must be signed in to change notification settings

guillaumeast/42_printf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

This project has been created as part of the 42 curriculum by gastesan.

ft_printf

42 C Bonus Grade

πŸ“‹ Table of Contents

πŸ“‡ Description

TL;DR

ft_printf is a reimplementation of the standard libc printf() function as a static library.

Precisions

The goal of this project is to reproduce the behavior of printf() while respecting strict constraints imposed by the 42 Norm.
It focuses on variadic functions, format string parsing, buffered output, and precise formatting rules.

Features

All mandatory conversions (c s p d i u x X %) are implemented as well as bonus flags (- 0 <space> # +), precision (.) and width fields.

Repository structure

.
β”œβ”€β”€ README.md
β”œβ”€β”€ libftprintf.h		# Public header
β”œβ”€β”€ includes/			# Private headers
β”œβ”€β”€ srcs
β”‚Β Β  β”œβ”€β”€ ft_printf.c
β”‚Β Β  β”œβ”€β”€ append.c
β”‚Β Β  β”œβ”€β”€ rules_parse.c
β”‚Β Β  └── rules_apply.c
└── libft/				# My libft static library

πŸ“– Instructions

Compilation

This project builds a static library intended to be linked with your programs.

Example compilation:

make bonus
cc <my_main.c> libftprintf.a -Iincludes

libft is automatically built and linked by make rules (used for string utilities and memory helpers).

Usage

ft_printf("Value: %08x | ptr: %p | str: %.5s\n", nb, ptr, str);

Both the output and return value matches standard printf():

  • the return value is the number of characters written (-1 on error)
  • the output is written directly to stdout using write().

🧠 Technical choices

Buffered output architecture

Instead of writing directly to stdout on every conversion, output is accumulated inside a dynamic buffer.
This significantly reduces syscall overhead and allows complex formatting to be applied before emission.

Exponential buffer growth

Buffers grow exponentially to minimize reallocations and ensure O(1) amortized append complexity.

Two-stage formatting pipeline

Formatting is split into two clear phases:

  1. Raw value append (conversion-specific)
  2. Rule application (precision, sign, width, padding, prefixes)

This separation improves readability, extensibility, and correctness.

Rule normalization

Parsing normalizes conflicting flags early:

  • - disables 0
  • precision disables 0
  • + overrides space
  • invalid flags for a conversion are ignored
  • ...

This avoids the original printf() undefined behaviors and ensures deterministic formatting.

Strict memory discipline

  • Temporary buffers are free'd immediately
  • No global state
  • All allocations are checked
  • No leaks under normal execution

Compiler format checking

The ft_printf prototype is annotated with __attribute__((format(printf, 1, 2))).

This enables the compiler and IDEs to perform the same format string checks as for the standard printf(), including:

  • format / argument type mismatches
  • missing or extra arguments

This provides early error detection at compile time and improves developer experience without impacting runtime behavior.

✌️ Same safety guarantees as printf, zero runtime cost.

🧩 Algorithm explanation

High-level flow

  1. Initialize the main output buffer t_buff.
  2. Iterate through the format string.
  3. Copy literal text until % to the main buffer.
  4. Parse formatting rules into a t_rules structure.
  5. Dispatch conversion to a dedicated append function.
  6. Convert raw value to a temporary buffer.
  7. Apply formatting rules to the temporary buffer.
  8. Append the result to the main buffer.
  9. Write the final buffer to stdout in one call.

Data structures

t_rules

Stores all parsed flags:

  • padding
  • width
  • precision
  • sign rules
  • conversion type

t_buff

Dynamic byte buffer with:

  • capacity
  • length
  • raw data pointer

Supports prepend, insert, and append operations with automatic exponential growth.

Complexity

  • Time: O(n) per formatted output
  • Space: proportional to output size
  • Each character is copied a bounded number of times

πŸ“š Resources

  • man 3 printf
  • man 3 stdarg
  • GNU libc printf documentation
  • 42 subject
  • Norm.v4

RTFM πŸ€“

πŸ€– AI usage notice

No code was generated by AI.

AI was used only to:

  • reason about edge cases and formatting behavior,
  • clarify tester/compiler logs,
  • refine explanations and documentation.

All technical decisions and implementations are original.

About

πŸ–¨οΈ ft_printf (42 Paris) β€” Extensible reimplementation of libc printf in C. Variadic arguments, flags, width, precision and conversions. Dynamic buffering, strict memory management, and modular design.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published