ℹ️ A static library that contains ft_printf, a function that mimics the real printf
100/100 ✅
- What is ft_printf?
- Requirements
- How does it work?
- How do I use the library?
- How do I test it?
- Makefile
- 42 Cursus
- Author
The third project at 42 programming school. It consists of a static library that contains ft_printf - a function that mimics the real printf - and another library (Libft, the first project at 42) with recoded standard functions in C to support the project's development. It's an extremely useful function that does a series of base conversions (decimal and hexadecimal) and makes the output much easier - especially when compared to its predecessor in 42 - the system call write. The function can be used in future projects.
Each function must be maximum 25 lines, not counting the function's own curly brackets.
Each line must be at most 80 columns wide, comments included.
A function can take 4 named parameters maximum.
You can't declare more than 5 variables per function.
You're not allowed to use: for , do...while , switch , case , goto ,
ternary operators such as `?' and VLAs - Variable Length Arrays.
The norminette (as we call the norm at 42) is in python and open source.
Its repository is available at https://github.com/42School/norminette.
In addition to the Norm, the subject have other requirements, which are:
Using the command libtool to create your library is forbidden.
Your Makefile must compile with the flags -Wall, -Wextra and -Werror.
✨ For this project we were introduced to the concept of variadic functions ✨
The printf function is one of the most known and used in the C language to give an output. It takes a string as an argument, this string may contain some placeholders (like %c for characters or %s for strings) whose original values are passed as arguments. The ft_printf has variable arguments, the only one being mandatory is the string that will be printed, otherwise it depends on how many placeholders are passed in this string. The function's return is the number of characters printed or -1 for error.
To create with a function like this, it must be a variadic function (with variable number of arguments), which is possible to achieve using the header <stdarg.h> and parameters like va_arg for the list arguments in order of occurrence or va_start and va_end to start and end the use of the argument list. For each conversion required by the subject, there's a function that converts the argument and returns the numer of bytes writed:
• %c print a single character.
• %s print a string of characters.
• %p The void * pointer argument is printed in hexadecimal.
• %d print a decimal (base 10) number.
• %i print an integer in base 10.
• %u print an unsigned decimal (base 10) number.
• %x print a number in hexadecimal (base 16).
• %% print a percent sign.
It aims to create a library called libftprintf.a from the source files.To create this library, clone the project:
git clone https://github.com/augustobecker/ft_printf ft_printf
Enter the repository:
cd ft_printf
Run Make (to run the Makefile that will compile the source code and create the library):
make
You should see a libftprintf.a file and some object files (.o).
Now to clean up (removing the .o files), call make clean:
make clean
Now you just have to add this header at your .c files and use the ft_printf function or any other from the library:
#include "library/ft_printf.h"
If you try to compile your .c files with clang using "clang example.c" you will get an undefined symbol error for Libftprintf functions.
You have to tell the file which library it's using:
clang example.c libftprintf.a
That's it. Now run it using ./a.out
To test the code we're going to be using @jgambard's Printf Tester. There are some good others but I'll only be covering this one.
To test the code in this repo Clone this repo and cd into it:
git clone https://github.com/augustobecker/ft_printf ft_printf
cd ft_printf/
Now, clone @jgambard's Libft Tester
git clone https://github.com/Tripouille/printfTester.git printfTester
Go into the test folder and run the mandatory test:
cd printfTester
make m
In case that your project or another project you are going to evaluate has a bonus, run the bonus test too:
make b
If you did everything correctly you should see something like this:
ℹ️ A handy automation tool to Run and compile your programs more efficiently.
A Makefile defines set of tasks to be executed, in shell script. These tasks are writed on a target in this format:
target: prerequisites
<TAB> recipe
such as:
fclean: clean
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
${REMOVE} ${NAME}
@echo
The recipe(the commands @echo and so forth) for the target fclean will only be executed when the target clean (the prerequisite) be executed. a target works without prerequisites too:
clean:
@echo "\n$(NAME): $(RED)object files were deleted$(RESET)"
${REMOVE} ${OBJS} ${BONUS_OBJS}
@echo
As you could see, there are a few variables inside the recipe. The variables can be assigned just as follow:
GREEN = \033[0;32m
RED = \033[0;31m
RESET = \033[0m
CC = clang
FLAGS = -Wall -Werror -Wextra
To use the variable value, just use the $ sign with parenthesis:
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
Using variables makes your Makefile more readable and easily modifiable. Try it :)
It is not necessary for the target to be a file. It could be just a name for the recipe, just as above. We call these phony targets.
But if you have a file with the exact name of your phony target inside of your repo, things can get a little weird. To protected your Makefile from this, just use phony and the name of all your phony targets used:
.PHONY: all clean fclean re bonus
Here at 42 school, the subject says that
Your Makefile must at least contain the rules $(NAME), all, clean, fclean and re.
The rules are the target, just name some of them as $(NAME), all, clean, fclean and re.
The rule $(NAME), in this case, should create the $(NAME) static library.
all is used to make the principal goal of your Makefile: create the $(NAME) static library.
clean removes the objects created to make the library.
fclean removes the objects created to make the library and the $(NAME).
re just removes the objects created to make the library and the $(NAME), to then recompile everything.
You can run a rule on your Makefile this way:
make $(target_name)
such as:
make clean
In the case of the target all, just type make
make
Choose your color, add it as a variable and use in your Makefile:
BLACK ="\[\033[0;30m\]"
RED ="\[\033[0;31m\]"
GREEN ="\[\033[0;32m\]"
YELLOW ="\[\033[0;33m\]"
BLUE ="\[\033[0;34m\]"
PURPLE ="\[\033[0;35m\]"
CYAN ="\[\033[0;36m\]"
WHITE ="\[\033[0;37m\]"
RESET ="\033[0m"
You could use it this way:
@echo "$(NAME): $(RED)$(NAME) was deleted$(RESET)"
So $(NAME) was deleted will be printed in red.
Cool, right?
Remember to reset the color when you're done, otherwise your terminal will keep with the last used colour.
42 is a global education initiative that proposes a new way of learning technology: no teachers, no classrooms, students learning from their fellow students (peer to peer learning), with a methodology that develops both computing and life skills. Not to mention that it's completely free of charge and open to all with no prerequisites.
Admissions at 42 are unlike other colleges. We use a merit-based admission process. The final step of the admission is the Piscine - This is part of the admissions process and requires 4 weeks of intensive and immersive coding. No prior coding experience is necessary at all.
You can check more about the admission process on the 42sp website: https://www.42sp.org.br or on my github repository: 42 Piscine
To see other projects developed by me at 42, click here: 42 Cursus