This project was carried out personally by Matteo Mattera.
ft_dprintf is a re-implementation of the C standard library function dprintf().
The goal of the project is to learn how variadic functions work in C
(<stdarg.h>)
The project produces a library, libftprintf.a, which exposes one function:
int ft_dprintf(int fd, const char *format, ...);Like the original, it writes the formatted output to the file descriptor fd
(standard output, standard error, a file, a pipe, a socket...) and returns the
number of characters printed, or -1 if a write error occurs. The buffer
management of the original dprintf() is not reimplemented.
| Conversion | Description |
|---|---|
%c |
Prints a single character |
%s |
Prints a string |
%p |
Prints a void * pointer in hexadecimal |
%d |
Prints a signed decimal (base 10) number |
%i |
Prints a signed integer (base 10) |
%u |
Prints an unsigned decimal (base 10) number |
%x |
Prints a number in hexadecimal (lowercase) |
%X |
Prints a number in hexadecimal (uppercase) |
%% |
Prints a percent sign |
The project is compiled with cc -Wall -Wextra -Werror.
make # builds libftprintf.a at the root of the repository
make clean # removes the object files
make fclean # removes the object files and libftprintf.a
make re # fclean + allThe library is created with ar.
#include <fcntl.h>
#include <unistd.h>
#include "ft_printf.h"
int main(void)
{
int len;
int fd;
/* Standard output */
len = ft_dprintf(1, "Hello %s! %d + %d = %i (0x%x)\n", "42", 1, 2, 3, 255);
ft_dprintf(1, "Printed %d characters\n", len);
/* Standard error */
ft_dprintf(2, "Error: %s\n", "something went wrong");
/* A file */
fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
return (1);
ft_dprintf(fd, "Pointer: %p, unsigned: %u\n", (void *)&fd, 42u);
close(fd);
return (0);
}cc -Wall -Wextra -Werror main.c -L. -lftprintf -o test
./testft_dprintf reads the format string in a single pass, from left to right:
- A
va_listis initialised withva_start. - Each character of the format string is inspected:
- if it is not a
%, it is written as is withwrite(fd, ...); - if it is a
%, the next character is the conversion specifier and the matching handler is called (c,s,p,d/i,u,x,X,%).
- if it is not a
- Each handler receives the file descriptor
fdand its argument (viava_arg), writes it directly tofdand returns the number of bytes written. - The counts are added up and the total is returned after
va_end. If anywritefails,-1is returned.
Numbers are printed with a recursive base conversion: the number is divided
by the base until a single digit remains, then digits are written on the way back.
The same function serves base 10 (d, i, u) and base 16 (x, X, p);
only the base string changes.
Special cases follow the behaviour of the original dprintf() on Linux:
%swith aNULLpointer prints(null);%pwith aNULLpointer prints(nil), otherwise0xfollowed by the address;INT_MINis handled by converting to a wider type before negating, to avoid overflow.
man 3 dprintfman 3 stdargman 2 write
AI was used for: README.