- About
- Supported Conversions
- Project Structure
- How It Works
- Variadic Functions
- Function Reference
- Installation & Compilation
- Usage
- Examples
- Return Value
- Makefile Targets
- Author
ft_printf is a project from the 42 School curriculum where the goal is to recode the standard C printf function from scratch. It is one of the most important foundational projects at 42 because the resulting library is reused in virtually every subsequent project.
The project introduces variadic functions in C β functions that accept a variable number of arguments β and teaches modular programming by separating each format specifier into its own handler. The implementation must match printf's return value behaviour and support the core set of conversion specifiers.
| Specifier | Description | Example Input | Example Output |
|---|---|---|---|
%c |
Single character | 'A' |
A |
%s |
String | "hello" |
hello |
%d |
Signed decimal integer | -42 |
-42 |
%i |
Signed decimal integer | 42 |
42 |
%u |
Unsigned decimal integer | 4294967295 |
4294967295 |
%x |
Hexadecimal integer (lowercase) | 255 |
ff |
%X |
Hexadecimal integer (uppercase) | 255 |
FF |
%p |
Pointer address | 0x7ffeefbff5a0 |
0x7ffeefbff5a0 |
%% |
Literal percent sign | %% |
% |
ft_printf/
β
βββ ft_printf.h # Header β prototypes and includes for va_list
βββ ft_printf.c # Core β parses format string and dispatches to handlers
β
βββ ft_print_char.c # Handles %c β writes a single character
βββ ft_print_str.c # Handles %s β writes a string (or "(null)")
βββ ft_print_nbr.c # Handles %d and %i β signed integer output
βββ ft_print_unsigned.c # Handles %u β unsigned integer output
βββ ft_print_hex.c # Handles %x and %X β hexadecimal output
βββ ft_print_ptr.c # Handles %p β pointer address output with "0x" prefix
β
βββ Makefile # Compiles everything into libftprintf.a
ft_printf parses the format string character by character. When it encounters a regular character, it writes it directly. When it encounters a %, it reads the next character to determine which conversion specifier to dispatch:
ft_printf("Hello %s! You are %d years old.\n", "Alice", 30);
β β β
β βββββββββββββ dispatch to ft_print_str
βββββββββββββββββββββ dispatch to ft_print_nbr
write directly βββΊ 'H','e','l','l','o',' '
The core dispatch logic in ft_printf.c:
int ft_printf(const char *format, ...)
{
va_list args;
int count;
va_start(args, format);
count = 0;
while (*format)
{
if (*format == '%')
{
format++;
count += ft_dispatch(*format, args);
}
else
count += ft_print_char(*format, args);
format++;
}
va_end(args);
return (count);
}Each handler returns the number of characters written, which are accumulated into count β matching the return value behaviour of the real printf.
ft_printf uses the <stdarg.h> macros to access a variable number of arguments at runtime:
| Macro | Purpose |
|---|---|
va_list |
Declares a variable to hold the argument list |
va_start(args, last) |
Initializes args, pointing to the argument after last |
va_arg(args, type) |
Retrieves the next argument as type |
va_end(args) |
Cleans up the va_list after use |
// Example: accessing arguments from a variadic call
va_list args;
va_start(args, format);
char c = va_arg(args, int); // %c
char *s = va_arg(args, char *); // %s
int n = va_arg(args, int); // %d / %i
unsigned int u = va_arg(args, unsigned int); // %u
va_end(args);| Function | File | Description |
|---|---|---|
ft_printf |
ft_printf.c |
Parses the format string and dispatches to the correct handler for each specifier. Returns total characters printed. |
| Function | File | Specifier | Description |
|---|---|---|---|
ft_print_char |
ft_print_char.c |
%c |
Writes a single character using write. Returns 1. |
ft_print_str |
ft_print_str.c |
%s |
Writes a string. If NULL is passed, prints (null). Returns the length of the string written. |
ft_print_nbr |
ft_print_nbr.c |
%d / %i |
Handles signed integers including INT_MIN. Returns digits printed. |
ft_print_unsigned |
ft_print_unsigned.c |
%u |
Handles unsigned integers up to UINT_MAX. Returns digits printed. |
ft_print_hex |
ft_print_hex.c |
%x / %X |
Converts an integer to hexadecimal. Uses lowercase "0123456789abcdef" or uppercase "0123456789ABCDEF". Returns digits printed. |
ft_print_ptr |
ft_print_ptr.c |
%p |
Casts the pointer to unsigned long and prints it in hexadecimal with a 0x prefix. Handles NULL pointers. Returns total characters printed. |
- GCC or Clang
- GNU Make
- Linux or macOS
git clone https://github.com/BrenoLSR/ft_printf.git
cd ft_printf
makeThis generates the static library libftprintf.a in the root directory.
To use ft_printf in another project, include the header and link the library:
#include "ft_printf.h"
int main(void)
{
ft_printf("Hello, %s! The answer is %d.\n", "world", 42);
return (0);
}Compile with:
gcc main.c -L. -lftprintf -o my_programOr integrate it into your project's Makefile:
PRINTF_DIR = path/to/ft_printf
PRINTF_LIB = $(PRINTF_DIR)/libftprintf.a
$(PRINTF_LIB):
make -C $(PRINTF_DIR)// Characters and strings
ft_printf("%c\n", 'Z'); // Z
ft_printf("%s\n", "42 SΓ£o Paulo"); // 42 SΓ£o Paulo
ft_printf("%s\n", NULL); // (null)
// Integers
ft_printf("%d\n", -2147483648); // -2147483648 (INT_MIN)
ft_printf("%i\n", 42); // 42
ft_printf("%u\n", 4294967295); // 4294967295 (UINT_MAX)
// Hexadecimal
ft_printf("%x\n", 255); // ff
ft_printf("%X\n", 255); // FF
ft_printf("%x\n", 0); // 0
// Pointers
int n = 42;
ft_printf("%p\n", &n); // 0x7ffd5e3a21bc (address varies)
ft_printf("%p\n", NULL); // (nil)
// Percent sign
ft_printf("100%%\n"); // 100%
// Multiple specifiers
ft_printf("[%c] [%s] [%d] [%x]\n", 'A', "hello", -1, 16);
// [A] [hello] [-1] [10]ft_printf returns the total number of characters written to the standard output, not counting the null terminator. This mirrors the behaviour of the original printf:
int ret = ft_printf("Hello, %s!\n", "world");
// ret == 13 (length of "Hello, world!\n")If an error occurs during writing, the return value is -1.
| Target | Description |
|---|---|
make / make all |
Compiles all .c files and generates libftprintf.a |
make clean |
Removes all .o object files |
make fclean |
Removes .o files and libftprintf.a |
make re |
Full recompile from scratch (fclean + all) |
"Tell me and I forget. Teach me and I remember. Involve me and I learn." β Benjamin Franklin