Skip to content

berkeldemir/ft_printf

Repository files navigation

42-ftprintf project-badge user-badge intra-badge

Ever wondered how printf works? Implement it yourself and see!

In this project of 42 Cursus, you will create your own printf function.

🖥️ Installation

Follow the instructions in your terminal:

git clone https://github.com/berkeldemir/ft_printf.git
cd ft_printf
make

⌨️ Usage

To try how it works you can create a main.c in the root of repository and type something like this:

#include "ft_printf.h"

int  main(void)
{
  ft_printf("%s!", "Hello World");
  return (0);
}

and then type this in your terminal:

gcc -o main main.c -L. -lftprintf
./main

if you see this output, then it works all good!:

Hello World!

👨‍💻 Code

Variadic functions are the cornerstone of this project, and I would like to start by discussing them.

1. Variadic Functions <stdarg.h>

You probably noticed that ft_printf function declared as

int	ft_printf(const char *str, ...);

Interesting there is '...', what is that?

It is what printf makes printf. Thanks to stdarg.h, we are allowed to create a function that takes unlimited number of undeclared arguments.

First we need a variable of type va_list.

va_list  args;

To unitialize it, we should use va_start(va_list ap, "which variable to start")

Remember you have to use va_end(va_list ap); at the end of your code before exit, to get no leaks.

va_start(arg, str);

And then basically you can call va_arg(va_list ap, "type"); to get the next value.

va_arg(arg, int);
va_arg(arg, char *);
va_arg(arg, unsigned int);
(...)

Examples above will work for %d (or %i), %s and %u in order. So it is important to correctly specify the character after %.

❗Remember that, you cannot go to the previous result of va_arg() function, it basically takes the next one every time.

If you want to do that you can use va_copy(va_list dst, va_list src); It will copy the existing va_list into another, to use back again.

2. (nil) or 0x0?

In printf if you want to print a NULL value with %p, it will give you "0x0" if you are working on a Mac and "(nil)" if you are on a Linux.

So i came up with this solution in my header file:

# ifdef __APPLE__
#  define NULLSTRING "(null)"
#  define NULLPOINTER "0x0"
# else
#  define NULLSTRING "(null)"
#  define NULLPOINTER "(nil)"
# endif

It basically looks if __APPLE__ defined in the system, if it is: NULLPOINTER macro will be "0x0" if not: it will be "(nil)".

3. How ft_base works?

While printing a number in hexadecimal way if the number is:

  • between 0-15 -> 1 character will be printed -- (0 and f)
  • between 16-25 -> 2 characters will be printed -- (10 and ff)
  • between 255-4095 -> 3 characters will be printed -- (100 and fff)
  • between 16^x-1 - 16^x -> x characters will be printed

It is also valid for integers because they are decimals (10 based):

  • between 0-9 -> 1 character will be printed
  • between 10-99 -> 2 characters will be printed
  • between 100-999 -> 3 characters will be printed
  • between 10^x-1 - 10^x -> x characters will be printed

So kinda doesn't it mean, we should repeat the situation till the number is 0-15?

Yes it does! Function will repeat itself while the number is greater than 15:

int	ft_base(unsigned long n, char *ref)
{
	int	count;

	count = 0;
	if (n >= 16)
		count += ft_base(n / 16, ref);
	count += ft_print_c(ref[n % 16]);
	return (count);
}

And then, it will be quitting itself repeatedly and printing 16 based indexed value from the given string.

if (c == 'x')
  count += ft_base(n, HEXADOWN);
else if (c == 'X')
  count += ft_base(n, HEXAUP);
# define HEXADOWN "0123456789abcdef"
# define HEXAUP "0123456789ABCDEF"

About

Ever wondered how printf works? Implement it yourself and see!

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors