# Table of Contents - [What is this gitbook for? | Guide](#what-is-this-gitbook-for-guide) - [Useful tools | Guide](#useful-tools-guide) - [Header files | Guide](#header-files-guide) - [C Structures | Guide](#c-structures-guide) - [Makefiles | Guide](#makefiles-guide) - [MiniLibX | Guide](#minilibx-guide) - [Linked Lists (todo) | Guide](#linked-lists-todo-guide) - [Libft | Guide](#libft-guide) - [MiniLibX Hook Examples | Guide](#minilibx-hook-examples-guide) - [File descriptors (FD) | Guide](#file-descriptors-fd-guide) - [MiniLibX Helper Function | Guide](#minilibx-helper-function-guide) - [Switch statement | Guide](#switch-statement-guide) - [Static variables | Guide](#static-variables-guide) - [Building the thing | Guide](#building-the-thing-guide) - [LIBC functions | Guide](#libc-functions-guide) - [pipex | Guide](#pipex-guide) - [get_next_line | Guide](#get-next-line-guide) - [minitalk | Guide](#minitalk-guide) - [What's a virtual machine ? | Guide](#what-s-a-virtual-machine-guide) - [Understand so_long | Guide](#understand-so-long-guide) - [Additional functions | Guide](#additional-functions-guide) - [Building the thing | Guide](#building-the-thing-guide) - [The basics (Docker, Images, etc...) | Guide](#the-basics-docker-images-etc-guide) - [Building the thing | Guide](#building-the-thing-guide) - [Understand Minishell | Guide](#understand-minishell-guide) - [Project Files | Guide](#project-files-guide) - [Born2beRoot | Guide](#born2beroot-guide) - [ft_printf | Guide](#ft-printf-guide) - [ft_putchar_fd | Guide](#ft-putchar-fd-guide) - [Philosophers | Guide](#philosophers-guide) - [so_long | Guide](#so-long-guide) - [ft_isascii | Guide](#ft-isascii-guide) - [ft_isdigit | Guide](#ft-isdigit-guide) - [ft_isalnum | Guide](#ft-isalnum-guide) - [Building the thing | Guide](#building-the-thing-guide) - [MiniRT | Guide](#minirt-guide) - [Building the thing | Guide](#building-the-thing-guide) - [push_swap | Guide](#push-swap-guide) - [Algorithms | Guide](#algorithms-guide) - [ft_substr | Guide](#ft-substr-guide) - [open() & read() | Guide](#open-read-guide) - [ft_strjoin | Guide](#ft-strjoin-guide) - [Inception (doing) | Guide](#inception-doing-guide) - [Core concepts | Guide](#core-concepts-guide) - [Variadic functions | Guide](#variadic-functions-guide) - [ft_transcendence (to-do) | Guide](#ft-transcendence-to-do-guide) - [ft_putendl_fd | Guide](#ft-putendl-fd-guide) - [FdF | Guide](#fdf-guide) - [Understand Philosophers | Guide](#understand-philosophers-guide) - [ft_striteri | Guide](#ft-striteri-guide) - [CPP06 (to-do) | Guide](#cpp06-to-do-guide) - [Understand minitalk | Guide](#understand-minitalk-guide) - [Graphics programming | Guide](#graphics-programming-guide) - [Level 1 & 2 | Guide](#level-1-2-guide) - [ft_strmapi | Guide](#ft-strmapi-guide) - [ft_itoa | Guide](#ft-itoa-guide) - [Bonus functions | Guide](#bonus-functions-guide) - [ft_lstsize | Guide](#ft-lstsize-guide) - [ft_lstadd_front | Guide](#ft-lstadd-front-guide) - [CPP09 (to-do) | Guide](#cpp09-to-do-guide) - [CPP08 (to-do) | Guide](#cpp08-to-do-guide) - [Building the thing | Guide](#building-the-thing-guide) - [Install your virtual machine | Guide](#install-your-virtual-machine-guide) - [Understand FdF | Guide](#understand-fdf-guide) - [ft_lstnew | Guide](#ft-lstnew-guide) - [Building the thing | Guide](#building-the-thing-guide) - [Understand MiniRT | Guide](#understand-minirt-guide) - [webserv (to-do) | Guide](#webserv-to-do-guide) - [CPP (00 - 04) (doing) | Guide](#cpp-00-04-doing-guide) - [CPP04 (doing) | Guide](#cpp04-doing-guide) - [Building the thing | Guide](#building-the-thing-guide) - [ft_lstdelone | Guide](#ft-lstdelone-guide) - [ft_lstlast | Guide](#ft-lstlast-guide) - [ft_lstclear | Guide](#ft-lstclear-guide) - [CPP (05-09) (to-do) | Guide](#cpp-05-09-to-do-guide) - [Understand pipex | Guide](#understand-pipex-guide) - [Building the thing | Guide](#building-the-thing-guide) - [ft_putstr_fd | Guide](#ft-putstr-fd-guide) - [Minishell | Guide](#minishell-guide) - [ft_lstmap | Guide](#ft-lstmap-guide) - [ft_lstadd_back | Guide](#ft-lstadd-back-guide) - [ft_lstiter | Guide](#ft-lstiter-guide) - [ft_bzero | Guide](#ft-bzero-guide) - [Building the thing | Guide](#building-the-thing-guide) - [NetPractice | Guide](#netpractice-guide) - [ft_toupper | Guide](#ft-toupper-guide) - [ft_isprint | Guide](#ft-isprint-guide) - [ft_putnbr_fd | Guide](#ft-putnbr-fd-guide) - [ft_strtrim | Guide](#ft-strtrim-guide) - [ft_memset | Guide](#ft-memset-guide) - [ft_tolower | Guide](#ft-tolower-guide) - [ft_isalpha | Guide](#ft-isalpha-guide) - [Exam Rank 05 | Guide](#exam-rank-05-guide) - [Team | Guide](#team-guide) - [ft_strlcpy | Guide](#ft-strlcpy-guide) - [P2P Evaluation - Questions | Guide](#p2p-evaluation-questions-guide) - [Theory | Guide](#theory-guide) - [ft_strlcat | Guide](#ft-strlcat-guide) - [ft_strlen | Guide](#ft-strlen-guide) - [ft_memcpy | Guide](#ft-memcpy-guide) - [ft_strchr | Guide](#ft-strchr-guide) - [ft_split | Guide](#ft-split-guide) - [Exam Rank 03 | Guide](#exam-rank-03-guide) - [CPP07 | Guide](#cpp07-guide) - [Exam Rank 04 | Guide](#exam-rank-04-guide) - [CPP05 | Guide](#cpp05-guide) - [Exam Rank 02 | Guide](#exam-rank-02-guide) - [ft_memmove | Guide](#ft-memmove-guide) - [CPP03 | Guide](#cpp03-guide) - [Functions used | Guide](#functions-used-guide) - [CPP02 | Guide](#cpp02-guide) - [Functions used | Guide](#functions-used-guide) - [Module 0 | Guide](#module-0-guide) - [ft_strncmp | Guide](#ft-strncmp-guide) - [CPP00 | Guide](#cpp00-guide) - [Functions used | Guide](#functions-used-guide) - [ft_memcmp | Guide](#ft-memcmp-guide) - [ft_strrchr | Guide](#ft-strrchr-guide) - [ft_calloc | Guide](#ft-calloc-guide) - [ft_strnstr | Guide](#ft-strnstr-guide) - [ft_strdup | Guide](#ft-strdup-guide) - [ft_memchr | Guide](#ft-memchr-guide) - [CPP01 | Guide](#cpp01-guide) - [Functions | Guide](#functions-guide) - [ft_atoi | Guide](#ft-atoi-guide) - [Level 1 | Guide](#level-1-guide) - [rev_print | Guide](#rev-print-guide) - [*ft_putstr | Guide](#-ft-putstr-guide) - [ft_swap | Guide](#ft-swap-guide) - [fizz_buzz | Guide](#fizz-buzz-guide) - [search_and_replace | Guide](#search-and-replace-guide) - [rotone | Guide](#rotone-guide) - [repeat_alpha | Guide](#repeat-alpha-guide) - [*ft_strcpy | Guide](#-ft-strcpy-guide) - [*ft_strlen | Guide](#-ft-strlen-guide) - [first_word | Guide](#first-word-guide) - [ulstr | Guide](#ulstr-guide) - [rot_13 | Guide](#rot-13-guide) - [Level 4 | Guide](#level-4-guide) - [fprime | Guide](#fprime-guide) - [rotstring | Guide](#rotstring-guide) - [ft_list_foreach | Guide](#ft-list-foreach-guide) - [sort_int_tab | Guide](#sort-int-tab-guide) - [ft_list_remove | Guide](#ft-list-remove-guide) - [rev_wstr | Guide](#rev-wstr-guide) - [sort_list | Guide](#sort-list-guide) - [Level 3 | Guide](#level-3-guide) - [ft_rrange | Guide](#ft-rrange-guide) - [ft_range | Guide](#ft-range-guide) - [ft_list_size | Guide](#ft-list-size-guide) - [flood_fil | Guide](#flood-fil-guide) - [hidenp | Guide](#hidenp-guide) - [lcm | Guide](#lcm-guide) - [add_prime_sum | Guide](#add-prime-sum-guide) - [expand_str | Guide](#expand-str-guide) - [epur_str | Guide](#epur-str-guide) - [ft_atoi_base | Guide](#ft-atoi-base-guide) - [str_capitalizer | Guide](#str-capitalizer-guide) - [print_hex | Guide](#print-hex-guide) - [rstr_capitalizer | Guide](#rstr-capitalizer-guide) - [paramsum | Guide](#paramsum-guide) - [pgcd | Guide](#pgcd-guide) - [tab_mult | Guide](#tab-mult-guide) - [Commented solution | Guide](#commented-solution-guide) - [Level 2 | Guide](#level-2-guide) - [ft_strspn | Guide](#ft-strspn-guide) - [alpha_mirror | Guide](#alpha-mirror-guide) - [camel_to_snake | Guide](#camel-to-snake-guide) - [last_word | Guide](#last-word-guide) - [ft_itoa | Guide](#ft-itoa-guide) - [do_op | Guide](#do-op-guide) - [ft_strpbrk | Guide](#ft-strpbrk-guide) - [wdmatch | Guide](#wdmatch-guide) - [*ft_strcmp | Guide](#-ft-strcmp-guide) - [ft_strcspn | Guide](#ft-strcspn-guide) --- # What is this gitbook for? | Guide The goal is to explain (almost) each project of the 42 program and our reasoning from A-Z to find a solution. We still invite you to try to do the projects by yourself because that's how you will learn best. Use this Gitbook only to understand some notions you are missing or when you are stuck ;) By copying and pasting a code you won't learn much. PS: We started our cursus on October 24, 2022. **If something is out of date, wrong or unclear don't hesitate** [**to tell us**](https://42-cursus.gitbook.io/guide/team) **and we will change it in the next few days.** **\-----** **PSS : THANKS A LOT FOR YOUR FEEDBACKS <3** We receive dozens of messages every week on linkedin, github or by e-mail that make us really happy. So we wanted to so THANK YOU. Don't hesitate to let us know what you'd like to see in this gitbook and to leave a kind message to us, from all around the world. Have fun ! Laura & Simon, from Switzerland (42 Lausanne) [NextUseful toolschevron-right](https://42-cursus.gitbook.io/guide/useful-tools) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Useful tools | Guide [🏁Header fileschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/header-files) [🧱C Structureschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/c-structures) [🔗Linked Lists (todo)chevron-right](https://42-cursus.gitbook.io/guide/useful-tools/linked-lists-todo) [📄Makefileschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/makefiles) [🔄Switch statementchevron-right](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement) [🗃️File descriptors (FD)chevron-right](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd) [PreviousWhat is this gitbook for?chevron-left](https://42-cursus.gitbook.io/guide) [NextHeader fileschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/header-files) Last updated 3 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Header files | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/header-files#what-is-a-header-file) What is a header file ? A header file is a file with extension .h which contains C function declarations and macro definitions to be shared between several source files. Note that a header file contains only function declaration and not the definitions of these functions. Copy void ft_putchar(char c); void ft_putstr(char *str); size_t ft_strlen(char *str); The declaration is only the prototype of the function. When we compile a C source file that includes a header file, these prototypes tell our source file that the functions declared in the header exist, what are their parameters, and what type of data do they return. The definitions of these functions can be written in as many C source files as you want to. i.e. the `LIBFT` project has one header file that contains the declaration of all the functions, but each function is written in a separate file so that the code remains readable and we include the same header file in all of them. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/header-files#header-protection) Header protection There's a lot of chance that you had some problems with your header files when trying to pass the Norm, for something called "HEADER PROT" (or something like that) but what the f\*\*\* is that ? Header protection is the code that wraps your entire header file : header\_example.h Copy #ifndef HEADER_EXAMPLE_H # define HEADER_EXAMPLE_H // your functions prototypes go here // your structures / typedefs go here as well #endif Before telling you exactly what this code do, I have to show you what a source file in which you include a header looks like when you compile it. Let's keep `LIBFT` as an example Above, I wrote 3 files, one header, and two source files that both include the same header file. Above is what the files look like before compilation, below, the same files after compilation. As you can see, the whole content of the header file was pasted at the top of each file (where we put the include statement before compilation). But since both our files will be compiled together in the same library, we don't have to include it in both files (or as many files as we included the header in), only including it in one of our source file is enough. That's the whole point of header protection, including headers only once. If I write the same header with header protection like so : Our source files after compilation will look like this : Why was the header included only once this time ? The header protection has a weird syntax, let's go over it line by line. This first line means `if not defined LIBFT_H`, the preprocessor checks if the macro `LIBFT_H` is defined or not. If it is not defined, it takes into account everything that is between this statement and the last statement of our header file. This is a macro definition, as you would do for any other values, the name of this macro must follow a specific format, check the Norm to find what it should be, but remember that the name of the file is `libft.h` and the macro for `example_header.h` is `EXAMPLE_HEADER_H`, I'm sure you can figure it out. Why do we define it ? So that next time we include the header file, this macro will be defined, so everything between `ifndef` and `endif` will be skipped as if it was never there. This way we only include the content of the header file at the top of one of all the source files. And finally, the last statement of the header protection: This statement ends the `if` we opened at the top of the header file with `ifndef`. #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/header-files#tldr) TLDR Header protection is a wrapper around all our header file content to include the content of this header only in one of the source file and not in every file. The syntax of the header protection is the following: ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/header-files#macros) Macros A macro in a header file is what you declare with the `#define` statement. You could, for example, define a macro called `WIN_H` that holds the height of the window you want to create, or `BUFFER_SIZE` to tell the program how much characters it has to read every time you call the function `read()` (that's what you have to do for [`get_next_line`](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line) ). Here are these examples: You could have multiple screen resolutions pre-defined and choose one or another by commenting a define statement or not like so: The above header file will set the `WIN_W` macro to `640` and the `WIN_H` macro to `360`. #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/header-files#what-are-macros-used-for) What are macros used for ? A defined macro can be used in every source files where the header is included. To use it, it is really simple, if we take the example of a window size we could write this: What will happen when you compile the above source file is that the preprocessor will replace the macros name with the values you set in the header file. In this example WIN\_H will be replaced by 360 and WIN\_W by 640. So the expected result of running this program will be this: [PreviousUseful toolschevron-left](https://42-cursus.gitbook.io/guide/useful-tools) [NextC Structureschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/c-structures) Last updated 3 years ago * [What is a header file ?](https://42-cursus.gitbook.io/guide/useful-tools/header-files#what-is-a-header-file) * [Header protection](https://42-cursus.gitbook.io/guide/useful-tools/header-files#header-protection) * [Macros](https://42-cursus.gitbook.io/guide/useful-tools/header-files#macros) sun-brightdesktopmoon libft.h Copy size_t ft_strlen(char *s); int ft_isdigit(int c); ft\_strlen.c Copy // This is what the code looks like before compilation #include "libft.h" size_t ft_strlen(char *s) { size_t i; i = 0; while (s[i]) i++; return (i); } ft\_isdigit.c Copy // This is what the code looks like before compilation #include "libft.h" int ft_isdigit(int c) { return (c >= 48 && c <= 57); } ft\_strlen.c Copy size_t ft_strlen(char *s); int ft_isdigit(int c); size_t ft_strlen(char *s) { size_t i; i = 0; while (s[i]) i++; return (i); } ft\_isdigit.c Copy size_t ft_strlen(char *s); int ft_isdigit(int c); int ft_isdigit(int c) { return (c >= 48 && c <= 57); } libft.h Copy #ifndef LIBFT_H # define LIBFT_H size_t ft_strlen(char *s); int ft_isdigit(int c); #endif ft\_strlen.c Copy size_t ft_strlen(char *s); int ft_isdigit(int c); size_t ft_strlen(char *s) { size_t i; i = 0; while (s[i]) i++; return (i); } ft\_isdigit.c Copy int ft_isdigit(int c) { return (c >= 48 && c <= 57); } Copy #ifndef LIBFT_H Copy # define LIBFT_H Copy #endif Copy #ifndef FILENAME_H # define FILENAME_H // other includes (stdio.h, stdlib.h, etc) // your function declarations // structrures declarations #endif example\_header.h Copy #ifndef EXAMPLE_HEADER_H # define EXAMPLE_HEADER_H # define WIN_H 720 # define WIN_W 1280 # define BUFFER_SIZE 42 char *get_next_line(int fd); #endif example\_header.h Copy #ifndef EXAMPLE_HEADER_H # define EXAMPLE_HEADER_H //# define 720P # define 360P # define BUFFER SIZE 42 # ifdef 720P # define WIN_W 1280 # define WIN_H 720 # endif # ifdef 360P # define WIN_W 640 # define WIN_H 360 # endif # include char *get_next_line(int fd); #endif main.c Copy #include "example_header.h" int main(void) { printf("Window Height: %d\n", WIN_H); printf("Window Width : %d\n", WIN_W); return (0); } Copy $> ./a.out $> Window Height: 360 $> Window Width : 640 $> sun-brightdesktopmoon --- # C Structures | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#introduction) Introduction **Structures** are a way to group several related variables into one place. Each variable in the structure is known as a **member** of the structure. To make it clearer, I will use the example of a library that wants to store information about books : * Book title * Book author * Book ID ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#difference-between-array-and-structures) Difference between array and structures Arrays allow you to store multiple variables of the same data type, an array of `int`, an array of `char`, etc. Structures allow you to store multiple variables of **different** data types. You could have one `int` member, one `char` member, multiple `double` members, etc. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#create-a-structure) Create a Structure Structures are generally declared in a header file so it is usable everywhere the header file is included. They are created using the **struct** keyword like this : main.h Copy struct [structure tag] { member definition; member definition; ... member definition; } [one or more structure variables]; #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#using-structure-tag-and-variables) Using structure tag and variables Structure tag and structure variables are concepts that are easily explained with examples. I'll explain the difference between the two usage. `a` and `c` will have the same content, as expected. `b` and `d` will also have the same content, as expected. The difference lies in the fact that you can create new variables based on the struct `s_st1` whenever you want in your code, but won't be able to do so for the anonymous structure. If you want to create a new variable based on the structure you'll have to do the following : As you can see, using a named structure can be easier if you need to declare a new variable later in your code. For example, our s\_book structure would be declared like this : circle-info Note that I named the structure since we would be using it to create multiple books in our code. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#accessing-structure-members) Accessing structure members To access a member of a structure, we have to use the **member access operator** `**.**`**.** To use it, we have to put a `.` between the structure variable name and the member we want to access. See the example below to find out how it's used in a program. When the above code is compiled and executed it produces the following result : ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#accesing-structure-pointer-members) Accesing structure pointer members To access a member of a structure pointer, we have to use another **member access operator** `**->**`**.** To use it, we have to put a `->` between the structure variable name and the member we want to access. See the example below to find out how it's used in a program. When the above code is compiled and executed it produces the following result : ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#defining-a-type-for-your-structure-typedef) Defining a type for your structure (typedef) We use the `typedef` keyword to create an alias name for data types. It is commonly used with structures to simplify the syntax of declaring variables. Look at the following example : We can use `typedef` to write an equivalent with a simplified syntax : ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#naming-convention) Naming convention To respect the 42 Norm, we have to name our `structures` and `typedef` in a certain way. This also makes it a lot easier to follow. Structure names must start with `s_` and typedefs must start with `t_`. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#why-structs) Why structs ? Suppose you want to store information about, to keep the same example, a book : title, author, id. You can create different variables `title`, `author`, `id` to store this information. What if you need to store information of more that one book ? Now, you need to create different variables for each informaiton per book : `title2`, `author2`, `id2`, etc. A better approach would be to have a collection of all related information under a single named `s_book` structure and use it for every book. #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#sources) Sources [![Logo](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2Fwww.tutorialspoint.com%2Fimages%2Fapple-touch-icon.png&width=20&dpr=3&quality=100&sign=2d7cab43&sv=2)Understanding C StructuresTutorialsPointchevron-right](https://www.tutorialspoint.com/cprogramming/c_structures.htm) [![Logo](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2Fwww.programiz.com%2Fsites%2Ftutorial2program%2Ffiles%2Ffavicon.png&width=20&dpr=3&quality=100&sign=5f4a3b68&sv=2)C struct (Structures)www.programiz.comchevron-right](https://www.programiz.com/c-programming/c-structures) [![Logo](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2Fwww.geeksforgeeks.org%2Fwp-content%2Fuploads%2Fgfg_200X200.png&width=20&dpr=3&quality=100&sign=dc7fd191&sv=2)C Structures - GeeksforGeeksGeeksforGeekschevron-right](https://www.geeksforgeeks.org/structures-c/) [![Logo](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2Fstackoverflow.com%2FContent%2FSites%2Fstackoverflow%2FImg%2Fapple-touch-icon.png%3Fv%3Dc78bd457575a&width=20&dpr=3&quality=100&sign=b839f4e&sv=2)What is the use of Struct Tag name in C programming?Stack Overflowchevron-right](https://stackoverflow.com/questions/44180120/what-is-the-use-of-struct-tag-name-in-c-programming) [PreviousHeader fileschevron-left](https://42-cursus.gitbook.io/guide/useful-tools/header-files) [NextLinked Lists (todo)chevron-right](https://42-cursus.gitbook.io/guide/useful-tools/linked-lists-todo) Last updated 2 years ago * [Introduction](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#introduction) * [Difference between array and structures](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#difference-between-array-and-structures) * [Create a Structure](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#create-a-structure) * [Accessing structure members](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#accessing-structure-members) * [Accesing structure pointer members](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#accesing-structure-pointer-members) * [Defining a type for your structure (typedef)](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#defining-a-type-for-your-structure-typedef) * [Naming convention](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#naming-convention) * [Why structs ?](https://42-cursus.gitbook.io/guide/useful-tools/c-structures#why-structs) sun-brightdesktopmoon Copy // With Structure Tag s_st1 struct s_st1 { int x; char c; } a = {100, 'a'}, b = {50, 'b'}; // Without Structure Tag struct { int x; char c; } c = {100, 'a'}, d = {50, 'b'}; Copy // Declaring new variable for the s_st1 structure. // You can do this whenever you want in your code. struct s_st1 e; e = {25, 'e'}; // Declaring new variable for the anonymous structure. // => go to the original structure declaration struct { int x; char c; } c = {100, 'a'}, d = {50, 'b'}, f; // Add a new variable to the list (i.e. 'f') // once that's done you can assign values to the variable f f = {25, 'f'}; Copy struct s_book { char title[50]; char author[50]; int book_id; }; // later in the code we could use this line to declare new Books struct s_book LOTR1 = {"The Lord of the Rings 1", "J.R.R. Tolkien", 44003415}; struct s_book LOTR2; strcpy(LOTR2.title, "The Lord of the Rings 2"); strcpy(LOTR2.author, "J.R.R. Tolkien"); LOTR2.book_id = 44003416; main.c Copy #include #include struct s_book { char title[50]; char author[50]; int book_id; }; int main(void) { // declaring 2 new books struct s_book book1; struct s_book book2; // Setting book1 members strcpy(book1.title, "The Lord of the Rings 1"); strcpy(book1.author, "J.R.R. Tolkien"); book1.book_id = 44003415; // Setting book2 members strcpy(book1.title, "The Lord of the Rings 2"); strcpy(book1.author, "J.R.R. Tolkien"); book1.book_id = 44003416; // Printing books information printf("%s - %s - %d\n", book1.title, book1.author, book1.book_id); printf("%s - %s - %d\n", book2.title, book2.author, book2.book_id); return (0); } Copy The Lord of the Rings 1 - J.R.R. Tolkien - 44003415 The Lord of the Rings 2 - J.R.R. Tolkien - 44003416 main.c Copy #include #include struct s_book { char title[50]; char author[50]; int book_id; }; void printBook(struct s_book *book); int main(void) { // declaring 2 new books struct s_book book1; struct s_book book2; // Setting book1 members strcpy(book1.title, "The Lord of the Rings 1"); strcpy(book1.author, "J.R.R. Tolkien"); book1.book_id = 44003415; // Setting book2 members strcpy(book1.title, "The Lord of the Rings 2"); strcpy(book1.author, "J.R.R. Tolkien"); book1.book_id = 44003416; printBook(&book1); printBook(&book2); return (0); } void printBook(struct s_book *book) { printf("%s - %s - %d\n", book->title, book->author, book->book_id); } Copy The Lord of the Rings 1 - J.R.R. Tolkien - 44003415 The Lord of the Rings 2 - J.R.R. Tolkien - 44003416 Copy struct s_point { int x; int y; }; int main(void) { struct s_point p1, p2; } Copy typedef struct s_point { int x; int y; } t_point; int main(void) { t_point p1, p2; } Copy // incorrect structure struct point_structure { int x; int y; }; // correct structure struct s_point { int x; int y; }; // incorrect typedef typedef struct s_point { int x; int y; } point; // correct typedef typedef struct s_point { int x; int y; } t_point; sun-brightdesktopmoon --- # Makefiles | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#introduction) Introduction circle-exclamation I will mainly use the term _executable_ in the following examples, note that Makefiles can also be used to create a library. The steps to create a Makefile for a library are described later in this page. circle-exclamation Note that if you copy paste a Makefile example from this gitbook, you'll have to change every 4 spaces tabs, to single tabs as gitbook automatically converts a tab to a 4 spaces tab. circle-info You'll need a Makefile for alot of 42 projects, I think it's better if you understand what it does and how to modify it rather than just copying it from a Github. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#what-is-a-makefile-make) What is a Makefile / make ? Makefiles are basically sophisticated shell scripts that automate the repetitive tasks of compiling/recompiling many files. Make Is a Unix utility that is designed to start execution of a makefile. A Makefile is a special file that you create name _Makefile_, it contains shell commands. While in the directory containing this Makefile, you will run the _make_ command and the commands written in the Makefile will be executed. Make keeps track of the last time files (normally object files) were updated and only updates those files which are required to keep the sourcefile up-to-date. If you have a program with a lot of source and/or header files, when you change a file on which others depend, you must recompile all the dependent files. This is an extremely time-consuming task. A Makefile contains a list of _rules_. These rules tell the system what commands you want to execute. Most of the time, these rules are commands to compile, or recompile, a series of files. The rules are in two parts. The first line is called a _dependency line_ and the following line(s) are called _actions_ or _commands_. The action line(s) must be indented with a tab. Rule syntax: Copy RULE: DEPENDENCY LINE [tab]ACTION LINE(S) The dependency line is also made of two parts. The first part, before the colon, is the _target_ file and the second part, after the colon, are the _prerequisites._ It is called a _dependency line_ because the first part depends on the second part. Multiple _prerequisites_ files must be separated by a space. After the Makefile has been created, a program can be (re)compiled by typing _make._ _Make_ then reads the Makefile, creates a dependency tree and take whatever action is necessary. It will not necessarily do all the rules in the Makefile as all dependencies may not need to be updated. It will rebuild _target_ files if they are missing or older than the dependency file(s). Unless directed otherwise, make will stop when it encounters an error during the build process. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#simple-makefile-example) Simple Makefile example Let's start of with the following three files, _hello.c, hellofunc.c_ and _hello.h._ chevron-righthello.c[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#hello.c) chevron-righthellofunc.c[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#hellofunc.c) chevron-righthello.h[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#hello.h) Normally, you would compile these files by executing the following command : `gcc -Wextra -Wall -Werror hello.c hellofunc.c -I. -o hello` circle-info The `-I.` is included so that gcc wil look in the current directory (.) for the include file _hello.h_ This command compiles the two .c files and creates an executable named _hello_. The simplest Makefile you could create for these file would look something like : Next, I will describe what rules are present in every Makefiles, these are conventions rules, and are required by the 42 Norm. More complex Makefile will be described later. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#rules-conventions) Rules conventions As said above, there are some rules conventions, these are rules that are not mandatory but present in almost all Makefiles, this makes compiling and building, as well as cleaning easier. Plus, these rules are required in the 42 Norm. Rule name Description all Since the first rule encountered in the Makefile is executed when using the `make` command without any specific rule, the _all_ rule has to be placed first in the Makefile, it usually calls the $(NAME) rule as a dependency (see example below). $(NAME) This is the main rule, it has for target the name of the executable we want to create and it will link all object files in an executable. %.o: %.c This rule is not required in the 42 Norm but makes reading the Makefile much easier. This rule has for target any .o file, and for dependency the .c file with the same name. clean This rule is a simple cleaning rule that will delete all object files created during the build process, but leave the created executable untouched. fclean This rule is also a cleaning rule, it is dependent on the _clean_ rule to delete all object files. Once all object files are deleted, this rule will delete the created executable. re This rule will rebuild everything, it is dependent on the _fclean_ rule, which deletes every object file and the executable. Once all the object files and the executable are deleted, the _re_ rule calls the _all_ rule to rebuild everything. chevron-rightSimple Makefile respecting the convention (everything described)[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#simple-makefile-respecting-the-convention-everything-described) chevron-rightSimple Makefile respecting the convention (expanded variables)[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#simple-makefile-respecting-the-convention-expanded-variables) ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#variables-naming-convention) Variables naming convention There's a rule convention, for which rules are expected in every Makefile, and there's also a naming convention for variable. I'll describe here the variables that are expected in a Makefile, and explain why it's named this way for the ones that are not very clear. Variable Description NAME The buid target name (executable / library / other) CC This variable contains the compiler gcc for C g++ for C++ CCFLAGS This variable contains the compiler flags. i.e. for 42 we have to use -Wall -Werror -Wextra CPPFLAGS This variable contains the compiler preprocessor flags. i.e. : -I to specify the include directory (see complete examples below) -D MACRO=value to define a macro at compiling time (used in Get Next Line) circle-info Note that CPPFLAGS doesn't mean it's the C++ compiler flags, here the "PP" part stands for PreProcessor ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#automatic-variables) Automatic variables There's a lot of so-called _automatic variables_ that you can use in your Makefiles, I'll describe and explain (with examples) only the most used ones (=> the ones that will be the most useful for you in the 42 Cursus). Automatic vairable Descrption $@ The file name of the target of the rule. $< The name of the first prerequisite. $? The names of all the prerequisites that are newer than the target, with spaces between them. If the target does not exist, all prerequisites will be included. $^ The names of all the prerequisites, with spaces between them. circle-info You can find more specific descriptions for Automatic Variables here : [https://www.gnu.org/software/make/manual/html\_node/Automatic-Variables.htmlarrow-up-right](https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html) chevron-rightList of all other automatic variables[hashtag](https://42-cursus.gitbook.io/guide/useful-tools/makefiles#list-of-all-other-automatic-variables) * $% * $+ * $| * $\* * $(@D) * $(@F) * $(\*D) * $(\*F) * $(%D) * $(%F) * $( void printHello(void); #endif Makefile Copy hello: hello.c hellofunc.c gcc -Wextra -Wall -Werror hello.c hellofunc.c -I. -o hello Makefile Copy # This Makefile example contains some variables and automatic variables # Below is the same Makefile without the variables and automatic variables # NAME is a variable containing the name of the executable # we want to create. NAME = excutableName # SRC is a variable containing all .c files required to build the project # Note that every file name has to be separated by a space and that I # didn't use a wildcard (*.c) to get every file. # While the usage of a wildcard would be simpler, it is not authorized by # the 42 Norm as it is easier to input an unwanted file in the build # process by simply adding it in the src folder. SRC = main.c test.c # OBJ is a variable containing all .o files. # As you can see I wrote OBJ := and not OBJ = # The difference between := and = is that = is an assignement like we know # in C. := tells make to append the result to the variable # We have to append the result because what's on the right will be run for # every .c file # Whats on the right basically means : "for every .c file you find in the # SRC variable, give me the corresponding .o file". # This will then append the result for each .c file to the OBJ variable. # It simply replaces the .c in each files in the SRC variable by .o OBJ := $(SRC:%.c=%.o) # ALL is the first rule in the Makefile, making it the default rule when # calling the make command without specifying the rule. # As said in the description table above, this rule has the $(NAME) rule # as dependency and will therefore, call the $(NAME) rule all: $(NAME) # $(NAME) is, as said above, the main rule of the Makefile. # This rule has the OBJ variable as dependency, which means, if one or # more .o files are missing, make will try to build them (if a rule for # that exists) before running the $(NAME) commands. # When all the dependency are there, the commands will be executed. # This commande takes two automatic variables, $^ and $@ # # $^: The name of all the prerequisites, with space between them # $@: This corresponds to the name of the target, in this case this will # be executableName. $(NAME): $(OBJ) gcc -Wextra -Wall -Werror $^ -o $@ # %.o rule will compile one .c file to its correspondig object (.o) file # The %.o: %.c pattern specifies that in order to build something whose # file name ends with .o, you need to have a file that has the same prefix # but then ends with .c rather than .o. # $<: The name of the first prerequisite. # $@: This corresponds to the name of the target, in this case this will # be executableName. %.o: %.c gcc -Wextra -Wall -Werror -c $< -o $@ # CLEAN rule has no prerequisites # What it does is run the rm -f shell command followed by the content of # the OBJ variable, that is, every .o filenames. # This results in all the .o files being deleted. clean: rm -f $(OBJ) # FCLEAN rule has as prerequisite the CLEAN rule, which means that the # CLEAN rule will be run first. # When the CLEAN rule is done, the fclean commands will be run. # This results in all the .io files being deleted, as well as the created # library because it has the name $(NAME) fclean: clean rm -f $(NAME) # RE rule has as prerequisites the FCLEAN and ALL rules. # As the prerequisite are read from left to right, the first rule to be # executed will be the FCLEAN rule, then we'll have the ALL rule # Since there are no commands for the RE rule, once the ALL rule is done, # the RE rule will also be done. re: fclean all Makefile Copy NAME = excutableName SRC = main.c test.c OBJ := $(SRC:%.c=%.o) all: executableName executableName: main.o test.o gcc -Wextra -Wall -Werror main.o -o executableName main.o: main.c gcc -Wextra -Wall -Werror -c main.c -o main.o test.o: test.c gcc -Wextra -Wall -Werror -c test.c -o test.o clean: rm -f main.o test.o fclean: clean rm -f executableName re: fclean all Makefile Copy # This Makefile is a complete example to compile an executable. # SRC is a variable containing all the mandatory source filenames. # As you can see, I simply put the file names without the .c extension # The .c extension is added to each filename with the addsuffix filename # function. # This filename function has the following prototype # $(addsuffix suffix, names...) # The suffix will be added to every filename you add as second argument. SRC = $(addsuffix .c, main ft_isalpha ft_isdigit ft_isalnum ft_isascii ft_isprint) # OBJS is a variable containing all .o filenames. # As you can see, I wrote OBJS := and not OBJS = # The difference between := and = is that = is an assignement operator like # we know in C. := tells make to append the result to the variable. # We have to append the result because what's on the right will be run for # every .c file one by one. # Whats on the right basically means : "for every .c file you find in the # SRC variable, give me the corresponding .o filename". # This will then append the result for each .c file to the OBJ variable. # It simply replaces the .c from each file in the SRC variable by .o OBJS := $(SRC:%.c=%.o) # BONUS_SRC is a variable containing all the bonus source filenames. # As you can see, I simply put the filenames without the .c extension. # The .c extension is added to each file with the addsuffix filename # function. I also use this filename function to add _bonus suffix that is # required by most 42 subjects. # This filename function has the following prototype # $(addsuffix suffix, names...) # The suffix will be added to every filename you add as second argument. # Then I add an $(addprefix, names...) filename function around it to # add a prefix for the bonus directory. # The $(addprefix, names...) works like the addsuffix function but # instead of adding the text at the end of each filename, it adds it to # the start of each filename. BONUS_SRC = $(addprefix bonus/, $(addsuffix _bonus.c, ft_lstnew ft_lstadd_back ft_lstadd_front)) # BONUS_OBJS is a variable containing all bonus .o filenames. # This works the same way as the OBJS variable. BONUS_OBJS := $(BONUS_SRC:%.c=%.o) # SUPP_SRC is a variable containing all the additionnal source files. # It works the same way as the BONUS_SRC variable, adding the .c suffix # to every filename, then adding the supp/ prefix to every filename with # the $(addsuffix suffix, names...) and $(addprefix prefix, names...) # filename functions. SUPP_SRC = $(addprefix supp/, $(addsuffix .c, ft_putchar ft_putstr ft_putnbr)) # SUPP_OBJS is a variable containing all additionnal .o filenames. # It works the same way as the OBJS and BONUS_OBJS variables. SUPP_OBJS := $(SUPP_SRC:%.c=%.o) # As I did for the source and object files, I declared some variables for # things I don't want to write each time. # NAME is a variable containing the naem of the executable we want to # create NAME = executable # CC is a variable containing the compiler # usually gcc for C and g++ for C++ CC = gcc # CCFLAGS is a variable containing the compiler flags # -Wall : this flag enables all the warnings about constructions # -Wextra : this flag enables some extra warning flags that are not # enabled by -Wall # -Werror : this flag turns all warning into errors to stop the compiler # when it encounters a warning. # You can find what flags are actually enabled when using these flags # by following this link, it also describes in more details what each # flag does # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options CCFLAGS = -Wall -Werror -Wextra # INC_DIR is a variable containing the path of the include directory # Include directory is used to put all the .h files included in your # .c files. # By including the include directory as a preprocessor flag when # compiling your files, you don't have to specify the path each time # you include a header file. # You can simply write #include "main.h" instead of "../include/main.h" INC_DIR = . # CPPFLAGS is a variable containing the preprocessor flags # In this example, it only contains the -I flag which speicifies the # include directory path taken from the INC_DIR variable. CPPFLAGS = -I$(INC_DIR) # OBJS_BASBO is a variable containing all the object filenames for the # mandatory source files as well as the bonus source files. OBJS_BASBO = $(OBJS) $(BONUS_OBJS) # OBJS_ALL is a variable containing all the object filenames for the # mandatory, bonus and additionnal source files. OBJS_ALL = $(OBJS_BASBO) $(SUPP_OBJS) # RM is a alias variable for the rm -f shell command. # I say alias variable because I can use this instead of writing # rm -f each time I have to delete something. # If I don't put the -f option, using the rm function will generate an # error if a file does not exist, -f force the execution, wheter or not # the file to delete exists. RM = rm -f # ALL is the first rule in the Makefile, making it the default rule when # calling the make command without specifying the rule. # The rule has the $(NAME) rule as dependency and will therefore, # call the $(NAME) rule. all: $(NAME) # $(NAME) is the main rule of the Makefile. # This rule has the OBJS variable as a dependency, which means, if one # or more .o files are missing, make will try to build them (if a rule # for that exists) before running the $(NAME) commands. # When all the dependency are there, the commands will be executed. # The command executed is the gcc linking, it links all the .o files # into an executable file called $(NAME) $(NAME): $(OBJS) $(CC) $(CCFLAGS) $^ -o $@ # %.o rule will compile one .c file to its corresponding object (.o) file # The %.o: %.c pattern specifies that in order to build something whose # filename ends with .o, you need to have a file that has the same # prefix but ends with .c rather than .o. # $<: The name of the first prerequisite. # $@: This corresponds to the name of the target : what is on the left # side of the colon. %.o: %.c $(CC) $(CPPFLAGS) $(CCFLAGS) -c $< -o $@ # CLEAN rule has no prerequisites # What it does is use the $(RM) alias variable follow by the content of # the OBJS_ALL variable, that is, every .o filenames. # This results in all the .o files being deleted. clean: $(RM) $(OBJS_ALL) # FCLEAN rule has as prerequisite the CLEAN rule, which means that the # CLEAN rule will be run first. # When the CLEAN rule is done, the fclean commands will be executed. # This results in all the .o files being deleted, as well as the created # executable because it has the name $(NAME) fclean: clean $(RM) $(NAME) # RE rule has as prerequisites the FCLEAN and ALL rules. # As the prerequisites are read from left to right, the first rule to be # executed will be the FCLEAN rule, then we'll have the ALL rule. # Since there are no commands for the RE rule, once the ALL rule is done, # the RE rule will also be done. re: fclean all # BONUS rule works the same way as the $(NAME) rule but instead of # having the OBJS variable as dependency, it has the OBJS_BASBO variable # Since the OBJS_BASBO variable contains the OBJS and the BONUS_OBJS # variables, all the .o files contained in these two variables are # dependencies for this bonus rule. bonus: $(OBJS_BASBO) $(CC) $(CCFLAGS) $? -o $(NAME) # EVERYTHING rule works the same way as the $(NAME) rule but instead of # having the OBJS variable as dependency, it has the OBJS_ALL variable. # Since the OBJS_ALL variable contains the OBJS, BONUS_OBJS and # SUPP_OBJS variables, all the .o files contained in these two variables # are dependencies for this everything rule. everything: $(OBJS_ALL) $(CC) $(CCFLAGS) $? -o $(NAME) # .PHONY target specifies which targets are not file dependent # Take a look at the ".PHONY targets" section below on this page # for more details .PHONY: all clean fclean re bonus everything Makefile Copy # This Makefile is a complete example to compile a C library. # SRC is a variable containing all the mandatory source files # As you can see, I simply put the file names without the .c extension # the .c extension is added to each file with the addsuffix filename function # this filename function has the following prototype # $(addsuffix suffix, names…) # The suffix will be added to every file name you add as second argument. SRC = $(addsuffix .c, ft_isalpha ft_isdigit ft_isalnum ft_isascii ft_isprint) # OBJS is a variable containing all .o filenames. # As you can see I wrote OBJS := and not OBJS = # The difference between := and = is that = is an assignement operator # like we know in C. := tells make to append the result to the variable # We have to append the result because what's on the right will be run for # every .c file one by one. # Whats on the right basically means : "for every .c file you find in the # SRC variable, give me the corresponding .o filename". # This will then append the result for each .c file to the OBJ variable. # It simply replaces the .c from each file in the SRC variable by .o OBJS := $(SRC:%.c=%.o) # BONUS_SRC is a variable containing all the bonus source files # As you can see, I simply put the file names without the .c extension # the .c extension is added to each file with the addsuffix filename function # this filename function has the following prototype # $(addsuffix suffix, names...) # The suffix will be added to every file name you add as second argument. # Then I added an $(addprefix, names...) filename function around it to # add a prefix for the bonus directory. # The $(addprefix, names...). works like the addsuffix function but # instead of adding the text at the end of each filename, it adds it to # the start of each filename. BONUS_SRC = $(addprefix bonus/, $(addsuffix _bonus.c, ft_lstnew ft_lstadd_back ft_lstadd_front )) # BONUS_OBJS is a variable containing all bonus .o filenames. # This works the same way as the OBJS variable. BONUS_OBJS := $(BONUS_SRC:%.c=%.o) # SUPP_SRC is a variable containing all the additional source files # It works the same way as the BONUS_SRC variable, adding the .c suffix # to every filename, then adding the supp/ prefix to every filename SUPP_SRC = $(addprefix supp/, $(addsuffix .c, ft_putchar ft_putstr ft_putnbr)) # SUPP_OBJS is a variable containing all additional .o filenames. # It works the same way as the OBJS and BONUS_OBJS variables. SUPP_OBJS := $(SUPP_SRC:%.c=%.o) # As I did for the source and object files, I declared some variables for # things I don't want to write each time. # NAME is a variable containing the name of the archive we want to create NAME = libft.a # CC is a variable containing the compiler # usually gcc for C and g++ for C++ CC = gcc # CCFLAGS is a variable containing the compiler flags # -Wall : this flag enables all the warnings about constructions # -Wextra : this flag enables some extra warning flags that are not # enabled by -Wall # -Werror : this flag turns all warning into errors to stop the compiler # when it encounters a warning. # You can find what flags are actually enabled when using these flags # by following this link, it also describes in more details what each # flag does # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options CCFLAGS = -Wall -Wextra -Werror # INC_DIR is a variable containing the path of the include directory # Include directory is used to put all the .h file needed by your # library. # By including the include directory as a preprocessor flag when compiling # your files, you don't have to specify the path each time you include a # header file. # You can simply write #include "main.h" instead of "../include/main.h". INC_DIR = . # CPPFLAGS is a variable containing the preprocessor flags # In this example, it only contains the -I flag which specifies the # include directory path taken from the INC_DIR variable. CPPFLAGS = -I$(INC_DIR) # RM is an alias variable for the rm -f shell command. # I say alias variable because I can use this instead of writing # rm -f each time I have to delete something. # If I don't put the -f option, using the rm function will generate an # error if a file does not exist, -f force the execution, wheter or not the # file to delete exists. RM = rm -f # ARNAME is an alias variable for the ar rcs $(NAME) shell command. ARNAME = ar rcs $(NAME) # RANNAME is an alias variable for the ranlib $(NAME) shell command. RANNAME = ranlib $(NAME) # OBJS_BASBO is a variable containing all the object filenames for the # mandatory source files as well as the bonus source files. OBJS_BASBO = $(OBJS) $(BONUS_OBJS) # OBJS_ALL is a variable containing all the object filenames for the # mandatory, bonus and additionnal source files. OBJS_ALL = $(OBJS_BASBO) $(SUPP_OBJS) # ALL is the first rule in the Makefile, making it the default rule when # calling the make command without specifying the rule. # This rule has the $(NAME) rule as dependency and will therefore, # call the $(NAME) rule. all: $(NAME) # $(NAME) is the main rule of the Makefile. # This rule has the OBJS variable as a dependency, which means, if one or # more .o files are missing, make will try to build them (if a rule for # that exists) before running the $(NAME) commands. # When all the dependency are there, the commands will be executed. # The commands are what is described above in the variable declaration # section : # ARNAME : ar rcs $(NAME) # RANNAME : ranlib $(NAME) $(NAME): $(OBJS) $(ARNAME) $(OBJS) $(RANNAME) # %.o rule will compile one .c file to its correspondig object (.o) file # The %.o: %.c pattern specifies that in order to build something whose # file name ends with .o, you need to have a file that has the same prefix # but then ends with .c rather than .o. # $<: The name of the first prerequisite. # $@: This corresponds to the name of the target : what is on the left # side of the colon. %.o: %.c $(CC) $(CPPFLAGS) $(CCFLAGS) -o $@ -c $< # CLEAN rule has no prerequisites # What it does is use the $(RM) alias variable followed by the content of # the OBJS_ALL variable, that is, every .o filenames. # This results in all the .o files being deleted. clean: $(RM) $(OBJS_ALL) # FCLEAN rule has as prerequisite the CLEAN rule, which means that the # CLEAN rule will be run first. # When the CLEAN rule is done, the fclean commands will be run. # This results in all the .io files being deleted, as well as the created # library because it has the name $(NAME) fclean: clean $(RM) $(NAME) # RE rule has as prerequisites the FCLEAN and ALL rules. # As the prerequisite are read from left to right, the first rule to be # executed will be the FCLEAN rule, then we'll have the ALL rule. # Since there are no commands for the RE rule, once the ALL rule is done, # the RE rule will also be done. re: fclean all # The bonus rule works the same way as the $(NAME) rule but instead of # having the OBJS variable as dependency, it has the OBJS_BASBO variable. # Since the OBJS_BASBO variable contains the OBJS and the BONUS_OBJS # variables, all the .o files contained in these two variables are # dependencies for this bonus rule. # The commands are what is described above in the variable declaration # section : # ARNAME : ar rcs $(NAME) # RANNAME : ranlib $(NAME) bonus: $(OBJS_BASBO) $(ARNAME) $(OBJS_BASBO) $(RANNAME) # The bonus rule works the same way as the $(NAME) rule but instead of # having the OBJS variable as dependency, it has the OBJS_ALL variable. # Since the OBJS_ALL variable contains the OBJS, the BONUS_OBJS and the # SUPP_OBJS variables, all the .io files contained in these two variables # are dependencies for this everything rule. # The commands are what is described above in the variable declaration # section : # ARNAME : ar rcs $(NAME) # RANNAME : ranlib $(NAME) everything: $(OBJS_ALL) $(ARNAME) $(OBJS_ALL) $(RANNAME) Makefile Copy clean: rm -f *.o Copy .PHONY: clean clean: rm -f *.o sun-brightdesktopmoon --- # MiniLibX | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx#introduction) Introduction In this pages I will cover some information about MiniLibX, the library you'll be using for (at least) the three rank 2 graphical project (so\_long, FdF, Fract-ol). I found most of the information I needed to use MiniLibX on this [pagearrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html) . I didn't find much other documentation online, and this one has some examples on how to do the basics things but I'd like to improve some of their explanation a bit and add some more examples that I really missed when trying to understand better how MiniLibX works. ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx#installation) Installation circle-exclamation I did a big part of the project using MiniLibX on the school computer, so if you're running Window or Linux, go check this [linkarrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html#installation) to install it correctly on your machine. Here's the Makefile I used for my so\_long project (adapted a bit from the one I really used). Makefile Copy NAME = so_long SRC = $(addprefix src/, main.c utils.c draw.c map_parser.c path_checker.c game_utils.c map_parser_utils.c free.c) GNL_SRC = $(addprefix gnl/, gnl.c gnl_utils.c) PRINTF_SRC = $(addprefix ft_printf/, ft_print_c.c ft_print_d.c ft_print_p.c ft_print_s.c ft_print_u.c ft_print_x.c ft_printf.c) OBJ := $(SRC:%.c=%.o) GNL_OBJ := $(GNL_SRC:%.c=%.o) PRINTF_OBJ := $(PRINTF_SRC:%.c=%.o) CC = gcc CCFLAGS = -Wextra -Wall -Werror all: $(NAME) $(NAME): $(OBJ) $(GNL_OBJ) $(PRINTF_OBJ) $(CC) $(CCFLAGS) $^ -Lmlx -lmlx -framework OpenGL -framework AppKit -o $(NAME) %.o: %.c gcc $(CCFLAGS) -Imlx -Iincludes -c $< -o $@ clean: rm -f $(OBJ) $(GNL_OBJ) $(PRINTF_OBJ) fclean: clean make clean -C mlx/ rm -f $(NAME) re : fclean all [PreviousFile descriptors (FD)chevron-left](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd) [NextMiniLibX Helper Functionchevron-right](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function) Last updated 2 years ago * [Introduction](https://42-cursus.gitbook.io/guide/minilibx#introduction) * [Installation](https://42-cursus.gitbook.io/guide/minilibx#installation) sun-brightdesktopmoon sun-brightdesktopmoon --- # Linked Lists (todo) | Guide [PreviousC Structureschevron-left](https://42-cursus.gitbook.io/guide/useful-tools/c-structures) [NextMakefileschevron-right](https://42-cursus.gitbook.io/guide/useful-tools/makefiles) Last updated 3 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Libft | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft#project-description) Project description Since in most 42 projects we can't use any of the standard C library functions, the goal of this first project is to replicate some of the usual functions ourselves, as well as some additional functions. We have to build a library that we will be able to use in our future projects. [PreviousMiniLibX Hook Exampleschevron-left](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples) [NextLIBC functionschevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # MiniLibX Hook Examples | Guide circle-info `keycode` and `mousecode` here are the MacOS ones, on Linux they are different (the escape key on Mac is 53, it's 65307 on Linux) and probably even different on Windows. If you need to find what are hooks for MiniLibX, you can fin more information in the [Eventsarrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx/events.html) and [Hooksarrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx/hooks.html) chapter. Here under I'll show you some examples hooks showing the most important values and some values that are not described in the documentation. Copy #include "mlx.h" #define WINDOW_HEIGHT 720 #define WINDOW_WIDTH 1280 int main(void) { /* * this is the MLX initialisation, I only put it in the example so you can * better see what I am doing below */ t_env *env; env.mlx = mlx_init(); env.win = mlx_new_window(env.mlx, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_NAME); env.img = mlx_new_image(env.mlx, WINDOW_WIDTH, WINDOW_HEIGHT); env.addr = mlx_get_data_addr(env.img, &env.bits_per_pixel, &env.line_length, &env.endian); /* end of MLX initialisation */ /* Here I will be declaring the hooks, see below for their implementation. */ mlx_hook(env.win, 4, 0, mouse_handler, &env); // mouse_handler will be called everytime a mouse down event is emitted mlx_hook(env.win, 2, 1L << 0, key_handler, &env); // key_handler will be called everytime a key is pressed mlx_hook(env.win, 17, 1L << 0, close_window, &env); // close_window is called when we click on the red cross to close the window mlx_loop_hook(env.mlx, render, &env); // Since MXL loops over and over again, we can use the mlx_loop_hook // to execute a function everytime MLX loops over. mlx_loop(env.mlx); } ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#simple-key_pressed_handler) Simple key\_pressed\_handler Since you can filter if you you want to listen to the `keypress` or `keyrelease` event, you can have two different key handlers, you might want to start doing something when we press the `space` key and stop it only when you release it. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FWVs1nnqNFCzTP9zpALnR%252Fkeycode.png%3Falt%3Dmedia%26token%3D2a57021d-374a-4dd4-9844-4868cf330381&width=768&dpr=3&quality=100&sign=f9b9e139&sv=2) key code circle-info I think here you can see how you could find what `keycode` corresponds to any key on your keyboard by looking at this function. ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#simple-mouse_handler) Simple mouse\_handler ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#mlx_loop_hook) mlx\_loop\_hook This hook will call a function every time through the MLX loop, we can use this to update what we show on screen. That's why I called it `render` or `draw` most of the time. For example, in `so-long` I use this hook to draw the map based on what changed. I draw the background completely again, to overwrite what was there, and then I redraw the walls and the player, but the player position can change based on `keypressed` events so the player moves along. The same way for collectibles, I don't want to draw them again if I already collected them (you can see the example I described [herearrow-up-right](https://github.com/Laendrun/42/blob/main/so_long/src/main.c#L43) ). circle-info These are just examples and simple handlers so that you can better understand how this works and adapt it based on your needs. [PreviousMiniLibX Helper Functionchevron-left](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function) [NextLibftchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft) Last updated 3 years ago * [Simple key\_pressed\_handler](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#simple-key_pressed_handler) * [Simple mouse\_handler](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#simple-mouse_handler) * [mlx\_loop\_hook](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples#mlx_loop_hook) sun-brightdesktopmoon Copy int key_handler(int keycode, t_env *env) { if (keycode == 53) ft_printf("ESCAPE"); else if (keycode == 0 || keycode == 123) ft_printf("LEFT (A / ARROW_LEFT)"); else if (keycode == 2 || keycode == 124) ft_printf("RIGHT (D / ARROW_RIGHT)"); else if (keycode == 1 || keycode == 125) ft_printf("DOWN (S / ARROW_DOWN)"); else if (keycode == 13 || keycode == 126) ft_printf("LEFT (A / ARROW_LEFT)"); else ft_printf("%d\n", keycode); return (0); } Copy int mouse_handler(int mousecode, int x, int y, t_env *env) { /* x and y parameters are the pixel coordinates of the mouse * in the window when the event was emitted * you can use them to check that the user clicked in a specific region * of the window */ if (mousecode == 1) ft_printf("Left Click"); else if (mousecode == 2) ft_printf("Right Click"); else if (mousecode == 3) ft_printf("Middle Click"); else if (mousecode == 4) ft_printf("Scroll UP"); else if (mousecode == 5) ft_printf("Scroll DOWN"); else if (mousecode == 6) ft_printf("Scroll right"); else if (mousecode == 7) ft_printf("Scroll left"); else ft_printf("%d\n", mousecode); } Copy int render(t_env *env) { draw_background(env); draw_map(env); draw_player(env); draw_moves(env); } sun-brightdesktopmoon --- # File descriptors (FD) | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#what-is-a-file-descriptor) What is a File Descriptor ? A file descriptor is an `int` variable that uniquely identifies an open file. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#terminology) Terminology Before going further with the explanation, I have to describe some terms that I will use on this page. Term Description File Descriptor This is the index of the File Table Entry in the file descriptor table. File Descriptor Table This is an array of File Table Entry, each process gets its own File Descriptor Table. File Table Entry A File Table Entry is a structure that contains informations about a file. Global File Table This is a system wide table containing all files. (It can't contain all files at once but the operating system will automatically update the table if you request a file that's not in this table). When you use a file descriptor, with the `read(2)` function for example, the following will happen : 1. Search for the file in the Global file table 1. If the file is found, go to next step. 2. If the file is not found, the operating system will update the Global file table to make the requested file available, then go back to step 1. 2. Create a File table entry in the File descriptor table for the requested file. 3. Assign the first unused File descriptor to the created file table entry. // insert schema here ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#standard-file-descriptors) Standard file descriptors In C, like in most Unix systems, there are 3 standards file descriptors that are automatically added to the file descriptor table. These file descriptors are the standard input/output file descriptor and always have these values : * 0 : this file descriptor represents the stdin (=> standard input, the terminal). This is the file descriptor used when reading user input from the terminal. * 1 : this file descriptor represents the stdout (=> standard output, the terminal). This is the file descriptor used when writing to the terminal. * 2 : this file descriptor represents the stderr (=> standard error output, the terminal). This is the file descriptor used when writing an error to the terminal, the information is written the same way, but a program which logs errors to a file can redirect everything written to the stderr file descriptor to a file. It's managed in another way by the operating system. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#examples) Examples When you use the `write(2)` function, you're actually using a file descriptor. The prototype of the `write(2)` function is as follows : As you can see, the first parameter to this function is an `int` called fd, sounds familiar right ? You can specify in which file to write with the first parameter, I'll make a quick example to show you how it could be used. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#how-it-works) How it works When you read bytes from a file descriptor, it remembers where in the file it was last time. This means, if you read 20 bytes from a file, next time you'll read from the same file descriptor, it will start reading from byte 21. Take a look at the example below. [PreviousSwitch statementchevron-left](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement) [NextMiniLibXchevron-right](https://42-cursus.gitbook.io/guide/minilibx) Last updated 1 year ago * [What is a File Descriptor ?](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#what-is-a-file-descriptor) * [Terminology](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#terminology) * [Standard file descriptors](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#standard-file-descriptors) * [Examples](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#examples) * [How it works](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd#how-it-works) sun-brightdesktopmoon Copy size_t write(int fd, const void *buf, size_t count); main.c Copy // Including the unistd header for the write(2) function #include // Including the fcntl header for the open(2) function #include // Prototypes of the functions declared under the main function void ft_putchar_terminal(char c); void ft_putchar_test_file(char c); // main function int main(void) { // calling the ft_putchar_terminal function with character T ft_putchar_terminal("T"); // calling the ft_putchar_test_file function with character F ft_putchar_test_file("F"); return (0); } /* This function will simply write one character to the terminal on the * standard output. As explained above, the fd for stdout is 1, so we put * 1 as a first parameter to the write(2) function. */ void ft_putchar_terminal(char c) { write(1, &c, 1); } /* This function will open a file called "test.txt" with the open(2) function. * Once the file is opened, store the file descriptor in the fd variable. * I then check if there was an error opening the file. * If no error, I write the character F in the file test.txt * If there is an error, I write an error message to the standard error output. */ void ft_putchar_test_file(char c) { int fd; /* Opening the test.txt file in Read/Write mode with open(2) function * then assigning the returned file descriptor value to the fd variable. */ fd = open("test.txt", O_RDWR); /* Checking if the file was correctly opened. * The open function returns -1 if there is an error opening the file. */ if (fd > 0) /* Writing the F character to the test.txt file by passing * its file descriptor as first parameter to the write(2) function. */ write(fd, &c, 1); else /* If there was an error opening the file, the value of fd will be -1 * thus it won't go inside the previous condition so I write an error * message to the stderr by passing the fd descriptor 2 as first parameter * to the write(2) function. */ write(2, "test.txt not found.\n", 20); } main.c Copy // Including the unistd header for the write(2) & read(2) function #include // Including the fcntl header for the open(2) function #include // Prototypes of the functions declared under the main function void ft_putchar_terminal(char c); void ft_putchar_test_file(char c); // main function int main(void) { // calling the ft_putchar_terminal function with character T ft_putchar_terminal("T"); // calling the ft_putchar_test_file function with character F ft_putchar_test_file("F"); return (0); } /* This function will simply write one character to the terminal on the * standard output. As explained above, the fd for stdout is 1, so we put * 1 as a first parameter to the write(2) function. */ void ft_putchar_terminal(char c) { write(1, &c, 1); } /* This function will open a file called "test.txt" with the open(2) function. * Once the file is opened, store the file descriptor in the fd variable. * I then check if there was an error opening the file. * If no error, I write the character F in the file test.txt * If there is an error, I write an error message to the standard error output. */ void ft_putchar_test_file(char c) { int fd; /* Opening the test.txt file in Read/Write mode with open(2) function * then assigning the returned file descriptor value to the fd variable. */ fd = open("test.txt", O_RDWR); /* Checking if the file was correctly opened. * The open function returns -1 if there is an error opening the file. */ if (fd > 0) /* Writing the F character to the test.txt file by passing * its file descriptor as first parameter to the write(2) function. */ write(fd, &c, 1); else /* If there was an error opening the file, the value of fd will be -1 * thus it won't go inside the previous condition so I write an error * message to the stderr by passing the fd descriptor 2 as first parameter * to the write(2) function. */ write(2, "test.txt not found.\n", 20); } sun-brightdesktopmoon --- # MiniLibX Helper Function | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function#simple-put_pixel-function) Simple put\_pixel function This is a simple function to put a pixel to the screen by its `x` and `y` coordinates. I based this function on what I found [herearrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html#writing-pixels-to-a-image) , and modified it a bit to make sure we only put a pixel that is inside the screen, without this check, the program could `segfault` if we try to set a value somewhere outside the window. Copy void ft_put_pixel(t_data *data, int x, int y, int color) { char *pxl; if (x >= 0 && x < WINDOW_WIDTH && y >= 0 && y < WINDOW_HEIGHT { pxl = data->addr + (y * data->line_length + x * (data->bits_per_pixel / 8)); *(unsigned int *)pxl = color; } } chevron-rightFinal code to draw a pixel[hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function#final-code-to-draw-a-pixel) Copy #include "mlx.h" #define WINDOW_WIDTH 1920 #define WINDOW_HEIGHT 1080 typedef struct s_data { void *img; char *addr; int bits_per_pixel; int line_length; int endian; } t_data; void ft_put_pixel(t_data *data, int x, int y, int color) { char *pxl; if (x >= 0 && x < WINDOW_WIDTH && y >= 0 && y < WINDOW_HEIGHT) { pxl = data->addr + (y * data->line_length + x * (data->bits_per_pixel / 8)); *(unsigned int *)pxl = color; } } int main(void) { void *mlx; void *mlx_win; t_data img; mlx = mlx_init(); mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello world!"); img.img = mlx_new_image(mlx, 1920, 1080); img.addr = mlx_get_data_addr(img.img, &img.bits_per_pixel, &img.line_length, &img.endian); ft_put_pixel(&img, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 0xFF0000); mlx_put_image_to_window(mlx, mlx_win, img.img, 0, 0); mlx_loop(mlx); } If you look closely, this will draw a red pixel at the very center of the window. ### [hashtag](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function#draw-line-function-naive-line-algorithm) Draw Line function (~Naive line algorithm) There is no function in MiniLibX to draw a line between two points, but this will be particularly useful when you try to code `FdF`, you'll have to join all your points by lines, so, here you go. circle-exclamation This function uses some function of the math library so make sure you can use it in your project and include it (`#include `). For `FdF`, `Fractol` and `so-long`, all the math library are authorized. circle-info You will have to find a way to make it pass the Norm, you can check how I did this [herearrow-up-right](https://github.com/Laendrun/42/blob/main/fdf/src/draw.c#L27) . [PreviousMiniLibXchevron-left](https://42-cursus.gitbook.io/guide/minilibx) [NextMiniLibX Hook Exampleschevron-right](https://42-cursus.gitbook.io/guide/minilibx/minilibx-hook-examples) Last updated 3 years ago * [Simple put\_pixel function](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function#simple-put_pixel-function) * [Draw Line function (~Naive line algorithm)](https://42-cursus.gitbook.io/guide/minilibx/minilibx-helper-function#draw-line-function-naive-line-algorithm) sun-brightdesktopmoon Copy void ft_draw_line(t_data *data, int x1, int y1, int x2, int y2, int color) { int step; int x; int y; int i; int delta_x; int delta_y; delta_x = x2 - x1; delta_y = y2 - y1; if (abs(delta_x) >= abs(delta_y)) step = abs(delta_x); else step = abs(delta_y); delta_x = delta_x / step; delta_y = delta_y / step; x = x1; y = x2; i = 0; while (i < step) { ft_put_pixel(data, x, y, color); x += delta_x; y += delta_y; i++; } } sun-brightdesktopmoon --- # Switch statement | Guide The `switch` and `case` statements cannot be used most of the time since they are not in the `Norm`. It could be useful in some exams, and you can use it there since there is no `Norm` during the exams. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#switch-statement) Switch statement The `switch` and `case` statements help control complex conditional and branching operation. ### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#examples) Examples I'll take as example one of the exercises of the `exam rank 02 - level 2`, the [`do_op`](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op) one, go read the subject there, then come back here. I'll first write it using if and else if statements, then I'll write the exact same thing using the `switch` statement. #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#if-...-else-if) If ... else if Copy if (av[2][0] == '+') printf("%d", atoi(av[1]) + atoi(av[3])); else if (av[2][0] == '-') printf("%d", atoi(av[1]) - atoi(av[3])); else if (av[2][0] == '*') printf("%d", atoi(av[1]) * atoi(av[3])); else if (av[2][0] == '/') printf("%d", atoi(av[1]) / atoi(av[3])); else if (av[2][0] == '%') printf("%d", atoi(av[1]) % atoi(av[3])); #### [hashtag](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#switch) Switch As you can see, both codes are pretty similar, but I personally think that the `switch` statement is clearer and easier to write. The switch statement takes a bit more place but could be useful in some cases. You can find more details about it [herearrow-up-right](https://www.w3schools.com/c/c_switch.php) . [PreviousMakefileschevron-left](https://42-cursus.gitbook.io/guide/useful-tools/makefiles) [NextFile descriptors (FD)chevron-right](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd) Last updated 3 years ago * [Switch statement](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#switch-statement) * [Examples](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement#examples) sun-brightdesktopmoon Copy swtich (av[2][0]) { case '+': printf("%d", atoi(av[1]) + atoi(av[3])); break; case '-': printf("%d", atoi(av[1]) - atoi(av[3])); break; case '*': printf("%d", atoi(av[1]) * atoi(av[3])); break; case '/': printf("%d", atoi(av[1]) / atoi(av[3])); break; case '%': printf("%d", atoi(av[1]) % atoi(av[3])); break; } sun-brightdesktopmoon --- # Static variables | Guide We are not going to remake the history when it is well done. For this theoretical part we recommend you to consult the page if you don't know what's a static variable, which is excellent. [![Logo](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2Fwww.geeksforgeeks.org%2Fwp-content%2Fuploads%2Fgfg_200X200.png&width=20&dpr=3&quality=100&sign=dc7fd191&sv=2)Static Variables in C - GeeksforGeeksGeeksforGeekschevron-right](https://www.geeksforgeeks.org/static-variables-in-c/) [Previousopen() & read()chevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide In this part, we will not give you the solution. We will try to describe the steps you need to go through to successfully write your own printf :) triangle-exclamation The allowed functions for this project are: `malloc, free, write, va_start, va_arg, va_copy, va_end`. Any other function used will cause the project to fail You will also have to make a Makefile and a header file with all the functions you will use. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing#general-formulation) General Formulation --------------------------------------------------------------------------------------------------------------------------------- _The thing I love to do before coding is to start by stating the problem on paper. Describe each step precisely before going on an endless madness._ This is one way of thinking and one way to solve the problem, among many others. 1. The printf function will write each character of the intial string, one by one, until it finds a %. 2. When it finds a %, it will look at the element in the next index/position. It will find the character that will define the type of the first variable argument. 3. Depending on what it finds, it will call a method that will display the argument of the particular type at output. -> if there is a "s" after the %, then you will need a function that displays strings. -> if there is a "d" after the %, then you will need a function that displays numbers. etc. 4. Once the first variable argument has been written, you go back to step 1, until the string is finished (aka, until you find a null character (\\0)). circle-exclamation (1 - 4): Don't forget to count the number of characters printed each time, in order to return the final number of characters at the end of the function. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing#specific-example) Specific example --------------------------------------------------------------------------------------------------------------------------- Let's take a closer look at this example and **try to translate the next sentences into code.** ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FpjzopgaWiRcykdeagYvg%252Fprocess.PNG%3Falt%3Dmedia%26token%3Dd25b62b5-03cd-4a74-9e49-d13ae431caf4&width=768&dpr=3&quality=100&sign=c4d496de&sv=2) visual example 1. Our program will write the characters from index 0 to 16, one by one, while incrementing the "count" variable. _\-> At this stage of the program the printf function should have displayed "hello my name is " and the number the function returns is 17._ 2. Once it encounters the '%' character, it stops writing and it will look one position further. -_\> At this stage we are pointing at the position/index 18._ 3. The program will now check the type of the element in this position (the position after the %). In our case, the type of the first dynamic argument is 's' (%s). 4. You will have to print one by one, the characters of the type the program has just found. As it is a string, we can for example use the "putstr" function that we created in the "libft" project to print each character. Don't forget to also count the number of characters that will be printed from this string and to add it to the initial count. 5. Once the first dynamic argument (the one corresponding to %s) has been displayed, you can come back to the initial sentence and continue the work. -_\> At this stage of the program the printf function should have displayed "hello my name is Laura" and the number the function returns is 21 (= total of character displayed)._ 6. Our program will then write again each character, one by one, from index 20 to 27 while incrementing the "count" variable. 7. The program will again find a % (position 28), stop writing and look for the next element. 8. The program will now check the type of the element in this position (the position after the %). In our case, the type of the second dynamic argument is 'd' (%d). That means that you will call a function that prints the number. -_\> At this stage of the program the printf function should have displayed "hello my name is Laura and I'm 23"._ 9. Our program will then write again each character, one by one, from index 30 to the end while incrementing the "count" variable. _\-> At this stage of the program the printf function should have displayed "hello my name is Laura and I'm 23 years old" and the number the function returns is 42 (42 characters printed in total)._ And that's it ! The printf project is pretty easy to get right! I won't give you the answer because it's always better to do it yourself (and this one is not that hard) :) I think the steps above should help you to succeed 80-90% of the project. Then there are some subtleties that I'll let you discover (spoiler alert: display a pointer or hexadecimal is a bit harder than displaying just a character). Good luck with you printf... it will be a reallyyyy useful function for all the other projects that you will need to do [PreviousVariadic functionschevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions) [Nextget\_next\_linechevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line) Last updated 1 year ago * [General Formulation](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing#general-formulation) * [Specific example](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing#specific-example) sun-brightdesktopmoon sun-brightdesktopmoon --- # LIBC functions | Guide [ft\_isalphachevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha) [ft\_isdigitchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit) [ft\_isalnumchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum) [ft\_isasciichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii) [ft\_isprintchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint) [ft\_strlenchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen) [ft\_memsetchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset) [ft\_bzerochevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero) [ft\_memcpychevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy) [ft\_memmovechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove) [ft\_strlcpychevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy) [ft\_strlcatchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat) [ft\_toupperchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper) [ft\_tolowerchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower) [ft\_strchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr) [ft\_strrchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr) [ft\_strncmpchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp) [ft\_memchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr) [ft\_memcmpchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp) [ft\_strnstrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr) [ft\_atoichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi) [ft\_callocchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc) [ft\_strdupchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup) [PreviousLibftchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft) [Nextft\_isalphachevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha) Last updated 3 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # pipex | Guide [▪️Understand pipexchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex) [▪️Functions usedchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used) [▪️Building the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing) [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing) [NextUnderstand pipexchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # get_next_line | Guide This project is about programming a function that returns a line read from a file descriptor. This project will not only allow you to add a very convenient function to your collection, but it will also make you learn a highly interesting new concept in C programming: **static variables.** Before starting, we recommend you to watch the video below to better understand the subject. It's in french but you can add english subtitles. _The video lasts 20 minutes but it will be the most worthwhile minutes of your life ;)_ Well, now that you have an overview of what we ask you to do, let's get started :) [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing) [Nextopen() & read()chevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # minitalk | Guide Well... like almost all the first times I read the topics of the 42 projects, I didn't understand much of the terms used. I will try to make you understand all these terms to better carry out the project later. Okay. Here we go. Let's try to understand the subject first. [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing) [NextUnderstand minitalkchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # What's a virtual machine ? | Guide Very briefly, a **virtual machine** (VM) is a machine in your machine. **Virtualization** is the art of running on the same physical machine, several systems as if they were running on separate physical machines. To better understand what I'm saying and for you to better visualize what it is for, let's go back to the basics. We will take the example of a computer server, as a machine since that's what we have to create in this project. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#components-of-a-computer-server) Components of a computer server ---------------------------------------------------------------------------------------------------------------------------------------------------------------- A physical server has a number of hardware elements such as a motherboard, a CPU (processor), some RAM to store information temporarily, a hard disk to store information for a longer period of time, a network card and many other components. An operating system is installed on top and it can contain several applications. A virtual machine will use the hardware of the machine it is running on (CPU & memory i.e.), but everything inside will be different. The virtual machine can have a different operating system and many different applications. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fu86lDVNTSuEwljPyySrI%252Fimage.png%3Falt%3Dmedia%26token%3Dd0a11ca3-82d8-4175-b79e-c85fd1081a81&width=768&dpr=3&quality=100&sign=636c1fdf&sv=2) You can see in the diagram that I added a "virtualization layer". This step is performed by a hypervisor. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#hypervisor) Hypervisor ---------------------------------------------------------------------------------------------------------------------- A **hypervisor** is a piece of software that enables a user to create and run one or more virtual machines simultaneously. A hypervisor is also known as the virtual machine monitor (VMM) and controls the resources of the host machine and allocates to each VM the resources it needs (memory, CPU...), making sure that these VM's do not interfere with each other. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#virtualbox) VirtualBox In 42, it is recommended to work with **"VirtualBox"** (or UTM if VB doesn't work). It's an open-source software that you will find on your Mac, if you are using one at a 42 school. Otherwise you can [install itarrow-up-right](https://www.virtualbox.org/manual/ch02.html) . It acts as a hypervisor, creating a VM (virtual machine) where the user can run another OS (operating system). ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fu9ekoE97TQ7UHWuTd02i%252Fimage.png%3Falt%3Dmedia%26token%3Daa9fa369-6da8-4a9b-8eed-3f3eb92d8b67&width=768&dpr=3&quality=100&sign=646eda50&sv=2) [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#operating-system) Operating System ---------------------------------------------------------------------------------------------------------------------------------- Every machine runs on an **operating system (OS)**, which is a set of programs that allows to run and control a machine. In other words, it's the interface between the user, the programs and the computer components. For example, Apple machines run mainly on macOS. Other machines can run on Windows or Linux, which are other two known operating system. Your virtual machine will also have to use an operating system. You will have the choice between Debian and CentOS. Let's see the difference between these two triangle-exclamation The subject changed since we wrote this so make sure to read your subject correctly before validating your project. We'll update this guide when we have checked what the differences are exactly. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#debian-vs-centos) Debian VS CentOS `Debian` was one of the first Linux distributions and has been available since 1993. Debian offers a higher degree of control and customization of its configuration. Released in 2004, `CentOS` is commonly used in the IT world on a large scale. CentOS ensures enterprise-level security, thus making it safe for users. * Debian is a lot easier to update then CentOS when a new version is released. * Debian is more user-friendly and supports many libraries, filesystems and architecture. It also has more options for customisation. * If you are a larger business CentOS offers more Enterprise features and excellent support for the Enterprise software. If you are a beginner, 42 recommends you to use Debian. circle-info I will continue this GitBook with Debian. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#undefined) --------------------------------------------------------------------------------------------------------- [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#what-is-the-purpose-of-virtual-machines) What is the purpose of virtual machines? --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The very first point, which is obvious, is that it is **more convenient and cheaper** to install a virtual machine than to buy another computer. Moreover, **the maintenance of VMs is very low** compared to the maintenance of a server (or other physical machine). And on top of all that, **you save a lot of space**. Instead of storing X number of machines at home, they are all on the same machine. When a physical server crashes, it can be complex to recover the data it contained. **The software aspect of VMs simplifies data backup**. While your VM is running, it is possible to obtain a backup thanks to a snapshot of the VM and its data. In case of an incident, this snapshot allows you to restore the VM to its previous state. Virtualization allows you to **increase the security of your data** by partitioning them and isolating services on different servers. Each VM is isolated from the others, including the host system. This limits the risks of propagation in case of malware intrusion. Moreover, **if a virtual machine crashes, the other VMs are not affected**. But it can also simply allow you to **test operating systems** or **be used as a test environment** for other things. circle-check **To summarize...** A virtual machine is a machine that is inside a host machine. It will behave exactly the same way as any other machine; it has an operating system and some apps. There are several advantages to having a virtual machine: * Inexpensive * Save physical space (stock) * Less maintenance than a physical machine * Data backup simplified * Increased security Now that you have some theory, we can start the practice by installing our first virtual machine ! See you in the next section [PreviousBorn2beRootchevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot) [NextInstall your virtual machinechevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine) Last updated 1 year ago * [Components of a computer server](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#components-of-a-computer-server) * [Hypervisor](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#hypervisor) * [VirtualBox](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#virtualbox) * [Operating System](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#operating-system) * [Debian VS CentOS](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#debian-vs-centos) * [](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#undefined) * [What is the purpose of virtual machines?](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine#what-is-the-purpose-of-virtual-machines) sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand so_long | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#goal) Goal chevron-rightProject-specific guidelines[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#project-specific-guidelines) You have to build a simple 2D game (top-down or platformer) * The goal of the game is to collect all objects present on the map to unlock an exit. * We have to be able to use W, A, S and D to move around. * The player can move in all four directions (up, down, right, left). * The player can't go through walls. * The total move count must be displayed at every move in the shell. * Pressing the ESC key must close the window and exit the program correctly. * Clicking on the red cross must close the window and exit the program correctly. * Using MiniLibX Images is mandatory. In short, you'll have to create a simple 2D game, top-down or viewed from the side. The subject in itself is fairly clear on what you have to do, I'll take some time on the next page to explain some of the core concepts you'll have to know before starting to build your game. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#before-starting) Before Starting Before starting to work on this project and read what I wrote, I encourage you to take some time and read the documentation of the MiniLibX [herearrow-up-right](https://harm-smits.github.io/42docs/libs/minilibx) , that's not the "official" documentation but it is still better explained there. There's also a MiniLibX section on this Gitbook where I put some helper functions that I used as well as some hooks that might be useful for this project. You should also choose what type of games you want to build, a top-down view, or one that is viewed from the side (like a platformer). circle-info A 2D top-down game is a type of video game that is played from a top-down perspective, meaning that the camera is positioned above the game world and the player views the game from an overhead perspective. In a 2D top-down game, the game world is typically represented in two dimensions, meaning that the game world is shown as a flat plane rather than a fully three-dimensional space. In a 2D top-down game, the player usually controls a character that is represented by a single sprite or 2D graphic, and moves the character around the game world by using the arrow keys or WASD keys on the keyboard, or by using a gamepad or joystick. The player typically interacts with the game world by moving the character around the game world, collecting items, solving puzzles, and defeating enemies. 2D top-down games are often used to create a sense of nostalgia or retro style, as they were popular in the early days of video gaming. They are also well-suited for certain types of gameplay, such as turn-based strategy games or games that involve a lot of exploration and puzzle-solving. circle-info A 2D platformer game is a type of video game that involves navigating a character through a series of levels or environments by running, jumping, and avoiding obstacles and enemies. In a 2D platformer game, the game world is typically represented in two dimensions, meaning that the game world is shown as a flat plane rather than a fully three-dimensional space and is shown from a side (Mario is a good example of that). In a 2D platformer game, the player usually controls a character that is represented by a single sprite or 2D graphic, and moves the character around the game world by using the arrow keys or WASD keys on the keyboard, or by using a gamepad or joystick. The player typically interacts with the game world by moving the character around the game world, collecting items, solving puzzles, and defeating enemies. 2D platformer games often involve a series of levels that the player must progress through, with each level becoming increasingly difficult as the player advances. The player may also have the ability to earn power-ups or special abilities that can help them navigate through the levels more easily. 2D platformer games are a popular genre of video game, and have been around since the early days of video gaming. They are often known for their fast-paced action and challenging gameplay, and have been a staple of the video game industry for many years. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#examples-2d-games) Examples 2D games Here are three well known example of 2D games that exist and from which you can inspire if you need ideas. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Ff0u7jJmBOWtVyJOJgSS5%252Fhotline_miami.avif%3Falt%3Dmedia%26token%3D4df32c4a-8f89-4940-81e0-19622edfd67d&width=768&dpr=3&quality=100&sign=ce4a71d3&sv=2) Hotline Miami circle-info Learn more about Hotline Miami [herearrow-up-right](https://en.wikipedia.org/wiki/Hotline_Miami) ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fe3VzWGhcWtOSwdi68NV3%252Fsuper_mario_bros.jpg%3Falt%3Dmedia%26token%3D94aa0030-37bd-478b-a6e5-ebb7a8c2dd71&width=768&dpr=3&quality=100&sign=8916b121&sv=2) Super Mario Bros. circle-info I think you all know what Super Mario Bros. is but you can find information [herearrow-up-right](https://en.wikipedia.org/wiki/Super_Mario_Bros.) and even play it online [herearrow-up-right](https://supermario-game.com/) . ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FCWWjait8wZssFUDwfI3f%252Fterraria.jpg%3Falt%3Dmedia%26token%3D59832805-71c0-4a4a-b148-4323c7df913e&width=768&dpr=3&quality=100&sign=fafd8b63&sv=2) Terraria circle-info You can find more information about Terraria [herearrow-up-right](https://en.wikipedia.org/wiki/Terraria) . [Previousso\_longchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/so_long) [NextCore conceptschevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts) Last updated 1 year ago * [Goal](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#goal) * [Before Starting](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#before-starting) * [Examples 2D games](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long#examples-2d-games) sun-brightdesktopmoon sun-brightdesktopmoon --- # Additional functions | Guide [ft\_substrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr) [ft\_strjoinchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin) [ft\_strtrimchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim) [ft\_splitchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split) [ft\_itoachevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa) [ft\_strmapichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi) [ft\_striterichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri) [ft\_putchar\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd) [ft\_putstr\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd) [ft\_putendl\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd) [ft\_putnbr\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd) [Previousft\_strdupchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup) [Nextft\_substrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide circle-exclamation Draw the pipes on paper, this helps, a lot. Before writing to the outfile, make sure you read from the correct end of the correct pipe. Here I'll give you some checklist on what you have to do to achieve this project. All the code for my pipex is available on my [Githubarrow-up-right](https://github.com/Laendrun/42-pipex) , if you have any question, don't hesitate to [contact](https://42-cursus.gitbook.io/guide/team) me (Simon), it'll be a pleasure to help you. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing#main-checklist) Main checklist * Check the existence of `infile` and `outfile` * be sure to understand what `>` does when the file does not exist * Create the necessary pipe (or pipes) * Create a child process for each command * Wait for all the processes to end before writing to the outfile circle-exclamation When using `here_doc`, the second argument is not a command ;) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing#execute-checklist) Execute checklist Remember that the `execve()` function needs the path to a binary file as parameter, so you'll have to find where the commands binaries are stored on your computer. Before going further, you have to know how to find any command binary. * Check in all possible locations if the binary (command) requested by the user exists. * "Build" the arguments array for the command. * Execute the command using `execve()` circle-info I know this is pretty small, but you have the information you need, you have to search and try things by yourself or else you won't learn anything. [PreviousFunctions usedchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used) [Nextminitalkchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk) Last updated 1 year ago * [Main checklist](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing#main-checklist) * [Execute checklist](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing#execute-checklist) sun-brightdesktopmoon sun-brightdesktopmoon --- # The basics (Docker, Images, etc...) | Guide [PreviousInception (doing)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing) [NextProject Fileschevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing/project-files) sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide For this function, this won't be a step by step building because describing each step that you need to take to build the function is pretty hard. I'll give you hints on what you have to do to achieve it. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#libft-functions) LIBFT functions For this project, I used some of the LIBFT functions you already know and built. I won't tell you exactly where and when you need to use them, but I'll give you what functions I used, maybe it'll give you some ideas on where to start or will unlock you if you're stuck on something. * FT\_STRCHR * FT\_STRDUP * FT\_STRLEN * FT\_SUBSTR * FT\_STRJOIN ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#additional-functions) Additional functions Apart from these 5 functions, I used 3 other functions : * `char *get_next_line(int fd)` * `char *_fill_line_buffer(int fd, char *left_c, char *buffer)` * `char *_set_line(char *line_buffer)` ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#explaining-the-functions) Explaining the functions Each of these 3 functions have a specific use in the project, I will here describe what each function does, this could give you an idea on what to do. Also, you'll see better where I could have used the LIBFT functions. chevron-right`char *get_next_line(int fd)`[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#char-get_next_line-int-fd) The main function get\_next\_line mainly makes some check about the file descriptor and the different memory allocation that could go wrong. Once all checks are done, it calls the `_fill_line_buffer` function to read in the file descriptor until it find a `\n` or `\0` character. Once the line variable is filled, we free the buffer so we don't have any memory leaks, since it's not used after that. Once the buffer is freed, we set the line with the `_set_line` function and we return the line, storing the return value of `_set_line` in a static variable so that next time we call the `get_next_line` function we have access to the first characters of the line that may have been read before. i.e. our file contains `1\n234\0`, our `BUFFER_SIZE` is 4. The first time we'll read through the file we'll read `1\n23` so what we are going to store in our static variable is `23` because the next time we call the function on the same file descriptor it will start reading at the `4` character in the file. chevron-right`char *_fill_line_buffer(int fd, char *left_c, char *buffer)`[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#char-_fill_line_buffer-int-fd-char-left_c-char-buffer) This function fills the `line` buffer. It will read BUFFER\_SIZE characters in each iteration until there's a `\n` or `\0` character in the line buffer. Each time through the loop, it will check if there is already data in the `left_c` buffer, if there is, it will append the new read characters to it. If not, it will duplicate the content of the read buffer into the `left_c` buffer. If a `\n` is found, it will break out of the loop and return the `left_c` buffer after appending the read characters to it. chevron-right`char *_set_line(char *line_buffer)`[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#char-_set_line-char-line_buffer) This function take the line buffer as parameter, it reads in it until a `\n` or `\0` character is found, meaning the end of a line, or the end of the file. This function sets the `line_buffer` a `\0` at the end of the line inside of it and it returns a substring of the buffer from the end of the line, to the end of the buffer. This substring is returned as `left_c`. These are the main functions for this project, I hope these explanation of what they each do in my project, can help you working on your own. In the next part you'll find the complete commented code for these 3 functions. I won't explain the other functions because you should have already corrected them and understood them. [PreviousStatic variableschevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/static-variables) [NextCommented solutionchevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution) Last updated 1 year ago * [LIBFT functions](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#libft-functions) * [Additional functions](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#additional-functions) * [Explaining the functions](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing#explaining-the-functions) sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand Minishell | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/understand-minishell#what-is-a-shell) What is a shell ? We have to build a minimalist shell, I think the best thing to start with is to understand what a shell is. This is a good definition of a shell I found on reddit (link to it below) Copy A shell or command shell is a program which has a special purpose: it reads keystrokes from the keyboard and interprets the "commands" that it receives in this way. The general idea is to have a human user interact with the command shell in order to accomplish system or computer maintenance related tasks, such as manipulating files or altering the configuration settings for various subsystems. One particular task of a command shell is to locate and start up other applications which have a specific task. For instance, you can start a web browser or a word processor program by typing in the appropriate name. Shells also typically are able to execute "batch files" or "shell scripts" which are text files that contain a series of commands that you would otherwise type in one after another. In this way you can automate repetitive tasks such as making a backup of a particular directory, or checking that the amount of disk space left is adequate. Knowing shell commands (both the built in commands and the utility programs) comes in handy when you are a system administrator. In my own experience (I have been my own linux system administrator for almost fifteen years) I can accomplish certain tasks way more efficiently using the keyboard issuing commands than firing up an application and shoving the mouse around. Linux in particular has several sophisticated command shell programs, of which my personal preference is bash. Windows traditionally has not given much attention to being able to perform tasks using a command shell. An MS-DOS like solution has always been the default. OS/2 had a pretty nifty command shell, but no one is using that anymore (where is the other half? - guffaw). But these last few years I hear Windows has a command shell solution that aims to be at least as good at what linux has to offer. I have never worked with it, so I have no opinion to offer. Source: [https://www.reddit.com/r/explainlikeimfive/comments/1vu6g7/eli5\_shell\_computing/arrow-up-right](https://www.reddit.com/r/explainlikeimfive/comments/1vu6g7/eli5_shell_computing/) [PreviousMinishellchevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/minishell) [NextFunctionschevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Project Files | Guide [PreviousThe basics (Docker, Images, etc...)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing/the-basics-docker-images-etc...) [Nextwebserv (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/webserv-to-do) sun-brightdesktopmoon sun-brightdesktopmoon --- # Born2beRoot | Guide If you are like me and **you know nothing about computers**, welcome! When I read the B2BR topic for the first time I was completely lost and didn't know where to start... lol. I will try my best to make sure you are not as lost as I was. And don't forget: try to understand what you are doing as much as possible :) **So... Let's dive into a brand new topic, which has not much to do with C programming anymore** We will first review all the (unknown) terms used in the subject. The goal is to understand what we are doing and be able to use this knowledge to build our virtual machine. We will then install our virtual machine and start by doing what is required in the subject. circle-exclamation For this project you will not only be evaluated on the creation of your virtual machine, but you will also be evaluated on theoretical elements (definitions & concepts). So make sure you understand everything ! [Previousft\_lstmapchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap) [NextWhat's a virtual machine ?chevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_printf | Guide In a nutshell, the printf function is a command to display a formatted string on the screen. circle-info The word "format" means that format specifiers, which begin with the % character, indicate the location and method of converting a data element (such as a number) into characters. Let's take an example. First, to use the printf function on C, you must include the "stdio" library (standard input/output). Copy #include int main() { printf("hello my name is Laura and i'm 23 years old\n"); printf("hello my name is %s and i'm %d years old\n", "Laura", 22); } On line 5 I did a printf of a simple string. On the next line, on line 6, I used the format specifiers so you can understand it better. **Both functions will return the same thing but it's in the construction that they differ.** ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FLqoIXuRlzyvCTN5uaNAZ%252FCapture.PNG%3Falt%3Dmedia%26token%3Da6e8b925-0ac2-4ea5-b4b8-a24e75e3c393&width=768&dpr=3&quality=100&sign=8681228a&sv=2) At the beginning of the sentence, each character is copied/written literally into the function's output. Then, when the function **finds a format specifier** (which starts with a % character), it will retrieve the argument that is in the same position and write it in a very specific way. For example when it finds the first %, it looks at what type it is. In our example, the first one is "s" so it will treat the first argument as a string, and use a specific method to copy this element into the function output. It will do the same thing when it finds the next %. Etc. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf#format-specifiers) Format specifiers The character after a '%' has different meanings. Let's just look at the ones we need to realize this project for school 42. Character Description % Prints a % character. d, i _Print an int_ as a signed [integerarrow-up-right](https://en.wikipedia.org/wiki/Integer) . %d and %i are synonymous for output, but are different when used with [`scanf`arrow-up-right](https://en.wikipedia.org/wiki/Scanf()) for input (where using %i will interpret a number as hexadecimal if it's preceded by 0x, and octal if it's preceded by 0.) u Print decimal unsigned int. x, X Print an unsigned int as a [hexadecimalarrow-up-right](https://en.wikipedia.org/wiki/Hexadecimal) number. x uses lower-case letters and X uses upper-case. s Print a null-terminated (\\0) string. c Print a single character (char). p Print the address of a pointer or any other variable. The output is displayed in hexadecimal value. It's a format specifier which is used if we want to print data of type (void \*). ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf#return-value-int) Return value (int) The prototype of the printf function is constructed like this: As you can see, the `printf` function returns a value of type int. But why ? In short, it is mainly about **checking for errors**. You can make sure that the operation was successful or not using the return value. Checking the return value of `printf` allows you to detect failure _early_ so you don't waste time attempting to write millions of lines when the first line already failed. * If a positive value is returned (indicating the number of characters written) it means the operation was successful. * If a negative number is returned there was some error. If you want to check what value the function returns, you can do a printf of your printf. [PreviousP2P Evaluation - Questionschevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions) [NextVariadic functionschevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions) Last updated 1 year ago * [Format specifiers](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf#format-specifiers) * [Return value (int)](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf#return-value-int) sun-brightdesktopmoon Copy int ft_printf(const char *format, ...); Copy int main() { int result = printf("Sentence to know how many %s\n", "characters were written"); printf("%d characters were written", result); } sun-brightdesktopmoon --- # ft_putchar_fd | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#subject) Subject Copy FT_PUTCHAR_FD (simplified) NAME ft_putchar_fd -- write character c on a specified file descriptor SYNOPSIS void ft_putchar_fd(char c, int fd); DESCRIPTION The ft_putchar_fd() function writes the character c on the file descriptor fd. PARAMETERS c: character to write fd: file descriptor on which to write RETURN VALUES ft_putchar_fd() does not return anything. AUTHORIZED EXTERNAL FUNCTIONS write(2) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#understandable-explanation) Understandable explanation This one is pretty straight forward, you already know how to write the `ft_putchar()` function, if you don't remember, look back at what you did during your Piscine. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#hints) Hints Take a look at the man for the `write(2)` function, the first parameter is... you guessed it ! A file descriptor, so I mean, do you really need to have the code for this ? I hope you can figure it out. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#commented-solutions) Commented solutions chevron-rightft\_putchar\_fd[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#ft_putchar_fd) [Previousft\_striterichevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri) [Nextft\_putstr\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#hints) * [Commented solutions](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd#commented-solutions) sun-brightdesktopmoon ft\_putchar\_fd.c Copy #include "libft.h" void ft_putchar_fd(char c, int fd) { /* first parameter is the file descriptor * second parameter is the address to the character */ write(fd, &c, 1); } sun-brightdesktopmoon --- # Philosophers | Guide The "philosophers' dinner" problem is a classic thought experiment and a well-known problem in computer science and distributed systems. The problem is typically presented in the context of five philosophers who are sitting around a circular table, with a plate of spaghetti in front of each of them, and a single fork between each pair of adjacent philosophers. The goal of each philosopher is to eat the spaghetti, but in order to do so, they must each use two forks. I recommend you to watch this video to better understand the problem triangle-exclamation the subject of 42 changes a bit from what is on the video - always read the subject carefully The problem is to design a protocol that allows each philosopher to pick up the two forks to their sides without causing a deadlock, where every philosopher is waiting for a fork that is currently being held by their neighbor. The protocol must ensure that no philosopher goes hungry, and that no two adjacent philosophers hold the same fork at the same time. The philosophers' dinner problem is an example of a concurrency problem in computer science and distributed systems, and it has been used as a case study in various fields, including operating systems, distributed algorithms, and concurrent programming. **It highlights the importance of designing protocols that can handle concurrent access to shared resources without causing deadlocks or other issues**. Now that you know the general idea, let's try to see together how we can solve this problem [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing) [NextUnderstand Philosopherschevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # so_long | Guide [▪️Understand so\_longchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long) [▪️Core conceptschevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts) [▪️Building the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing) [PreviousCommented solutionchevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution) [NextUnderstand so\_longchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_isascii | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#subject) Subject Copy ISASCII(3) (simplified) NAME isascii -- test for ASCII character SYNOPSIS int isascii(int c) DESCRIPTION The isascii() function tests for an ASCII character, which is any character between 0 and octal 0177 inclusive. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#understandable-explanation) Understandable explanation For this function, the man is self-explanatory, even though it doesn't tell you what the return values are... The `isascii()` function returns a non-zero value if the character passed as an `int` parameter is an ASCII character between 0 and octal 0177, this means characters between 0 and decimal 127, all characters displayed when you type the `man ascii` command. If the character is not an ASCII character between 0 and octal 0177, the `isascii()` function return `0`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#hints) Hints ft\_isascii.c Copy int ft_isascii(int c) { if (/* c is between 0 and decimal 127 */) return (/* non-zero value of your choice */); return (0); } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#commente-solution) Commente solution circle-exclamation This works mostly like the 3 other ones we built, there's a little catch though. chevron-rightft\_isascii[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#ft_isascii) [Previousft\_isalnumchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum) [Nextft\_isprintchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#hints) * [Commente solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii#commente-solution) sun-brightdesktopmoon ft\_isascii Copy #include "libft.h" int ft_isascii(int c) { /* checking if c is between 0 and decimal 127 */ if (c >= 0 && c <= 127) return (1); /* Note that I didn't return c for this one */ /* why ? if the value of c is 0, this function as to return a non-zero value too, so we can't return c */ return (0); } sun-brightdesktopmoon --- # ft_isdigit | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#subject) Subject Copy ISDIGIT(3) (simplified) NAME isdigit -- decimal-digit character test SYNOPSIS int isdigit(int c) DESCRIPTION The isdigit() function tests for a decimal digit character. The value of the argument must be representable as an unsigned char or the value of EOF. RETURN VALUES The isdigit() function return zero if the character tests false and return non-zero if the character tests true. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#understandable-explanation) Understandable explanation For this function, the man is self-explanatory, but I'll still explain it in other words. The `isdigit()` function return a non-zero value if the character passed as an `int` parameter is a decimal digit character (0 - 9). If the character is not a decimal digit character, the `isdigit()` function return `0`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#commented-solution) Commented solution triangle-exclamation Come on ! You really need the code for that function ? chevron-rightft\_isdigit[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#ft_isdigit) [Previousft\_isalphachevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha) [Nextft\_isalnumchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit#commented-solution) sun-brightdesktopmoon ft\_isdigit.c Copy int ft_isdigit(int c) { if (/* c value is one of the decimal digit characters in the ASCII table */) return (/* non-zero value of your choice */); return (0); } ft\_isdigit.c Copy #include "libft.h" int ft_isdigit(int c) { /* this checks the character against the ASCII table if c is a decimal digit */ if (c >= 48 && c <= 57) return (c); // here I'm returning c, as if it's a decimal digit it'll be non-zero return (0); // if we reach this point, c isn't a decimal digit } sun-brightdesktopmoon --- # ft_isalnum | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#subject) Subject Copy ISALNUM(3) (simplified) NAME isalnum -- alphanumeric character test SYNOPSIS int isalnum(int c) DESCRIPTION The isalnum() function tests for any character for which isalpha(3) or isdigit(3) is true. The value of the argument must be representable as an unsigned char or the value of EOF. RETURN VALUES The isalnum() function returns zero if the character tests false and returns non-zero if the character tests true. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#understandable-explanation) Understandable explanation For this function, the man is self-explanatory, but I'll still explain it in other words. The `isalnum()` function returns a non-zero value if the character passed as an `int` parameter is alphabetical or a decimal digit character. If the character is not alphabetical nor a decimal digit character, the `isalnum()` function returns `0`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#hints) Hints ft\_isalnum.c Copy int ft_isalnum(int c) { if (/* c isalpha or c isdigit */) return (/* non-zero value of your choice */); return (0); } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#commented-solution) Commented solution triangle-exclamation Come on ! You really need the code for that function ? chevron-rightft\_isalnum (variant 1)[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#ft_isalnum-variant-1) chevron-rightft\_isalnum (variant 2)[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#ft_isalnum-variant-2) [Previousft\_isdigitchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit) [Nextft\_isasciichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalnum#commented-solution) sun-brightdesktopmoon ft\_isalnum.c Copy #include "libft.h" int ft_isalnum(int c) { /* This checks makes use of the 2 preceeding functions we built */ if (ft_isalpha(c) || ft_isdigit(c)) return (c); //If we reach this point we can return c as it will be a non-zero value return (0); } ft\_isalnum.c Copy #include "libft.h" int ft_isalnum(int c) { /* This check is the same as the variant one but without using the pre-existing functions, it's longer to write, it could be useful if you don't want to have it being dependant on other functions */ if ((c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122)) return (c); // If we reach thi point we can simply return c as it will be a non-zero value return (0); } sun-brightdesktopmoon --- # Building the thing | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing#introduction) Introduction Minishell is a big project that requires a good communication between both of the group member and a good organization on how you divide the work that has to be done as to not do the same thing twice or not as the other expects it to work. Start by laying down the majors steps of the project and talk about how you want to work together and all of that before starting. If you want to do the bonuses, think about how you'll implement them from the beginning, it will be very hard to implement them later without redoing everything from scratch. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing#checklist-documentation) Checklist / documentation Here I'll give you the way we divided our work, I'm not telling you that is THE way to do it but it gives you an idea. We split the work in two main parts from the beginning, that were later splitted again into smaller parts : * Lexing / parsing * Execution Take some time to read / watch things about lexing and parsing, these subjects may seem a little boring but are really interesting and it will help you to know what they are for and at what time you'll need to use them. Some groups didn't do any lexing, take a look at what it is and decide if you want to use it or not. [PreviousFunctionschevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions) [NextCPP (00 - 04) (doing)chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing) Last updated 1 year ago * [Introduction](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing#introduction) * [Checklist / documentation](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing#checklist-documentation) sun-brightdesktopmoon sun-brightdesktopmoon --- # MiniRT | Guide 42's MiniRT project is a programming challenge that aims to model images using a technique called raytracing. The aim is to create realistic images representing a given scene, viewed from a specified angle. Here is an example: Example of a MiniRT (try hard version) Obviously, you can do it a little simpler. In the video above he did all the extras and really did a try-harder job (spoiler: mine will not be so great) To achieve this, **MiniRT uses a raytracing protocol**. Raytracing is a 3D image rendering method that simulates the behavior of light by tracing light rays from the virtual camera, and calculating the interaction of these rays with objects in the scene. _We will see it more in details later._ The scene modeled in MiniRT is made up of simple geometric objects such as spheres, planes or triangles. Each of these objects has its own properties, such as position, color and lighting system. Lighting systems can include ambient, diffuse or specular light sources, which contribute to the way objects are rendered. MiniRT's ultimate goal is to produce realistic images that capture the effects of shadow, reflection and refraction of light in the scene. This requires the implementation of efficient raytracing algorithms to simulate these light interactions. So... here we go. Now you are ready to dig into this big project. RayTracing will have no secrets for you in a few days ;) [PreviousLevel 1 & 2chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2) [NextUnderstand MiniRTchevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#main-checklist) Main checklist This is a checklist containing the main steps you have to do, I don't want to give you too much information, you still have to search things by yourself. * Create a data structure to store all required information about a philosopher * Create the correct number of philosopher * Create the correct number of threads * Create a routine * What each philosopher has to do ? In which order ? * Initiate the threads with said routine circle-info Some variables have to be shared between all philosophers so take this into account when creating your data structures. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#routine-checklist) Routine checklist * Create a loop that runs until any of your philosophers die circle-info If you have to loop until any of your philosphers die, it might be a good idea to check in the routine if any of your philosopher has died. That's basically it. Your philosophers have to do the following things (in order) in the routine. 1. Eat 2. Sleep 3. Think 4. Repeat The most complex thing in this project is to understand how threads work and how you can use mutexes to lock / unlock some values. Once you understood that, you "just" have to make each philosopher eat, sleep and think in a loop. Don't forget to print the logs when the state of your philosophers change. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#final-word) Final word That's basically it, the things you have to do are not the most complicated, the most important part of this exercise is to understand everything about threads and mutexes and all. Also, if you do the bonuses, you'll have to understand semaphores and processes. We already used processes, in a way or another by doing [Minitalk](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk) or [pipex](https://42-cursus.gitbook.io/guide/2-rank-02/pipex) , but semaphores are an all new subject. I don't want to add more details for this exercise, I want you to search information and really understand how everything works, this is the best I can do for you. But don't hesitate to [contact](https://42-cursus.gitbook.io/guide/team) us if you have any question, I'll be happy to help you with your project. [PreviousFunctions usedchevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used) [NextMinishellchevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/minishell) Last updated 1 year ago * [Main checklist](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#main-checklist) * [Routine checklist](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#routine-checklist) * [Final word](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing#final-word) sun-brightdesktopmoon sun-brightdesktopmoon --- # push_swap | Guide Push\_swap is a project that teaches you about sorting algorithms and how to optimize them. The project involves sorting a stack of integers using a limited set of operations (push, swap and rotate) and minimizing the number of moves. At the beginning, you must have one stack, called `stack a` with all your numbers placed next to each other. With the help of the operations below, at the very end, all the numbers in your `stack a` will have to be sorted. triangle-exclamation At the end, you don't need to return the sorted list, just the sequence of operations to sort the list. You can normalize the list if you need to To do this, you can have a second empty stack, called the `stack b`, on which you can temporarily send elements. Here are the operations you can use (and that you will have to code): * `sa (swap a)`: Swap the first 2 elements at the top of the stack a. Does nothing if there is only one or none. * `sb (swap b)` : Swap the first 2 elements at the top of the stack b. Does nothing if there is only one or none. * `ss` : sa and sb at the same time. * `pa (push a)`: Takes the first element on top of b and puts it on a. Does nothing if b is empty. * `pb (push b)`: Takes the first element on top of a and puts it on b. Does nothing if a is empty. * `ra (rotate a)`: Shifts all the elements of the stack a up by one position. The first element becomes the last. * `rb (rotate b)` : Shifts all the elements of the stack b one position upwards. The first element becomes the last one. * `rr` : ra and rb at the same time. * `rra` (reverse rotate a): Shifts all elements of the stack down one position. the stack a. The last element becomes the first. * `rrb` (reverse rotate b): Shifts all the elements of the stack b one position downwards. the stack b. The last element becomes the first. * `rrr` : rra and rrb at the same time. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap#examples) Examples **We have 6 random numbers**, placed on a first stack, called stack A, as follows. Obviously, stack B is empty at the beggining. Stack B will be used temporarily throughout your program, but must be empty again at the end, with the list sorted into stack A. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fij5SIDHSSvOhHj92oJ33%252Fimage.png%3Falt%3Dmedia%26token%3D69c35151-c512-4f44-8eb6-19cc22f1b607&width=768&dpr=3&quality=100&sign=8c98c5dc&sv=2) initial stacks Let's say we want to move an element from stack A to stack B. This can be done with the "PUSH" operation. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FALXRgodpBgdEsxRjTOad%252Fimage.png%3Falt%3Dmedia%26token%3D99d46e23-7cb5-403b-afd0-104ec0f3bba2&width=768&dpr=3&quality=100&sign=d552bb56&sv=2) PUSH example **The first element of stack A becomes the first element of stack B.** Don't forget then that the second element of the A stack becomes the first, and so on. Here stack B was empty, but if there were numbers in it, the first element of stack B would become the second and so on. The process is the same when you want to send an element from list B to list A. Let's continue with the modified list above. **We can also swap the first two numbers of a stack** by using the "SWAP" operation. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FSmQJOlQjeGF7H2Ea3cCZ%252Fimage.png%3Falt%3Dmedia%26token%3D74c476b3-cf8b-4d19-b259-06258bde8d8c&width=768&dpr=3&quality=100&sign=47194cb9&sv=2) SWAP example Here we can see that the only two numbers that have been impacted are the first two in the A stack. The logic remains the same when swapping two elements of the B stack. This one is easy. One last type of operation can be done. **The rotation**. There are two types of rotations: rotation and reverse rotation. All the numbers in the stack are affected this time. Normal rotation allows you to push all the numbers up and reverse rotation, all the numbers down. Here is a schematic example of both rotations: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FsiB3DTRrSAJF8nQ0hK8X%252Fimage.png%3Falt%3Dmedia%26token%3D89843cc8-6d97-4f2b-8787-1a1f258b8ae6&width=768&dpr=3&quality=100&sign=f1d00fab&sv=2) ROTATE example ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FKwUZNTLjTFmig6ioU3Jf%252Fimage.png%3Falt%3Dmedia%26token%3D55e18d0c-5d8a-482c-9d60-4dd4e879e88e&width=768&dpr=3&quality=100&sign=ae44f5ca&sv=2) REVERSE ROTATE example And that's it for the instructions. Of course you will need to combine all the instructions in order to write your own algorithm. I hope that these few examples will help you to better understand this project and make coding easier for you. Let's start now ! [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing) [NextAlgorithmschevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Algorithms | Guide Regarding the code, we don't learn anything new in this project. Except to master the management of chained lists or arrays and the structures. However, the most important concept that we discover in push swap is the algorithms. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#whats-an-algorithm) What's an algorithm ? An algorithm is a set of steps for solving a specific problem or completing a task. Think of it like a recipe that outlines how to make a cake from scratch. Each step is clearly defined and must be followed in a specific order to achieve the desired outcome. Another example would be solving a Rubik's Cube. When you see certain shapes, you have to execute certain instructions. **Algorithms can be applied to a wide range of problems, from simple arithmetic operations to complex machine learning models.** Learning algorithms, especially in the context of push\_swap, is useful for several reasons: * **Problem-solving skills**: Algorithms help develop problem-solving skills as it requires one to understand the problem, come up with a solution and then implement it. * **Understanding of data structures**: The "push\_swap" problem involves sorting data, so understanding algorithms helps in understanding different data structures like stacks and arrays and how to manipulate them. * **Improved efficiency**: Understanding algorithms helps improve the efficiency of code by reducing the number of operations required to solve a problem. * **Preparation for technical interviews**: Knowledge of algorithms is often tested in technical interviews as it provides insight into a candidate's problem-solving skills and understanding of basic computer science concepts. A problem can always have several solutions. Some solutions are more efficient than others. This means that one algorithm can be more efficient and optimized than another. This is called algorithmic complexity. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#algorithm-complexity) Algorithm complexity Algorithm complexity refers to the amount of resources (such as time or memory) required for an algorithm to solve a problem. It provides a way to measure and compare the efficiency of different algorithms. There are two main types of algorithm complexity: 1. **Time complexity**: measures the amount of time an algorithm takes to solve a problem. 2. **Space complexity**: measures the amount of memory an algorithm takes to solve a problem. #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#measurement-of-algorithmic-complexity) Measurement of algorithmic complexity The complexity is usually expressed using Big O Notation, which provides an upper bound on the resources required by the algorithm. The most classical approach is therefore to calculate the worst-case computation time. Let's take an example: Let's say you have an algorithm that takes 100 milliseconds to solve a problem with an input size of 10. If you double the size of the input, it might take maximum 200 milliseconds. If you have an input size of 30, it might take max. 300 milliseconds. Etc. This means the time complexity of the algorithm is O(n), where n is the size of the input. Here is a diagram that compares several levels of complexity/big O notations with each other: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fa2EaUcsJYBCqwer5shYi%252Fimage.png%3Falt%3Dmedia%26token%3D28855aa9-cec7-437d-8ea1-52ce82424088&width=768&dpr=3&quality=100&sign=69377548&sv=2) Algorithm comparisons 1. O(1) represents a constant time complexity, which means that the time required by the algorithm does not depend on the size of the input. For example, accessing an element in an array using an index is O(1). 2. O(n) represents a linear time complexity, which means that the time required by the algorithm grows linearly with the size of the input. For example, a simple linear search algorithm is O(n). 3. O(log n) represents a logarithmic time complexity, which means that the time required by the algorithm grows logarithmically with the size of the input. For example, a binary search algorithm is O(log n). 4. O(n^2) represents a quadratic time complexity, which means that the time required by the algorithm grows exponentially with the size of the input. For example, a simple bubble sort algorithm is O(n^2). It's important to note that Big O Notation provides an upper bound on the growth rate of an algorithm and is not an exact measure of the resources required by the algorithm. The actual resources required by an algorithm can be different from the estimate provided by Big O Notation. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#known-sorting-algorithms) Known sorting algorithms To achieve the push swap project, you will need to choose a sorting algorithm that will work with the intructions you are allowed to use and that will make the fewest possible moves. Below is an example of sorting algorithms and their complexity, according to three different methods for the time complexity and with one for the space complexity. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FOsCFOcmsKWChPAJLaFEW%252Fimage.png%3Falt%3Dmedia%26token%3Da236370e-cfca-4b3f-9d6b-8ff778570d65&width=768&dpr=3&quality=100&sign=a4da4cb5&sv=2) Complexity of sorting algorithms. Source: Big-O Cheat Sheet, 2016. Now it's up to you to choose which algorithm you will use! You can of course try to create your own if you can :-) Good luck with push\_swap ;) [Previouspush\_swapchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing) Last updated 1 year ago * [What's an algorithm ?](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#whats-an-algorithm) * [Algorithm complexity](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#algorithm-complexity) * [Known sorting algorithms](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms#known-sorting-algorithms) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_substr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#subject) Subject Copy FT_SUBSTR (simplified) NAME ft_substr -- extract a substring from a string SYNOPSIS char *ft_substr(const char *s, unsigned int start, size_t len); DESCRIPTION Allocate (with malloc(3)) and return a new string from the string s. This new string starts at index 'start' and has a maximum size of 'len'. PARAMETERS s: string from which to extract the new string start: start index of the new string in the string 's' len: maximum size of the new string RETURN VALUES ft_substr() returns the new string; NULL if the memory allocation failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#understandable-explanation) Understandable explanation `ft_substr` returns a substring of the string `s` passed as parameter. Here's an example ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#hints) Hints First we have to check if the `start` index is greater than the length of the string or not. We also have to check if the `start` plus the `len` is greater than the length of the whole string. Then we allocate enough memory for the substring, and copy from `s[start]` until we reach `len` characters copied into our new string. And finally we can return the substring. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#commented-solution) Commented solution chevron-rightft\_substr[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#ft_substr) [PreviousAdditional functionschevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions) [Nextft\_strjoinchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr#commented-solution) sun-brightdesktopmoon Copy ft_substr("Bonjour comment ca va?", 5, 8); => "ur comme" ft\_substr.c Copy #include "libft.h" char *ft_substr(const char *s, unsigned int start, size_t len) { size_t i; char *str; /* we first check that the string we received is not null * if it's the case we return NULL as we won't be able to take * a substring out of something empty */ if (!s) return (NULL); /* if the start index is greater than the length of the original * string we return an allocated empty string that can be freed * later on */ if (start > ft_strlen(s)) return (ft_strdup("")); /* if the len we have to copy is greater than the length of the string * starting at index start, that means we have to stop after we read * the whole string and that the allocated size has not to be * equal to the len received as parameter but only the size we will * copy plus one for the NUL-terminating character * this let's us only allocate memory that is really necessary */ if (len > ft_strlen(s + start)) len = ft_strlen(s + start); /* we then allocate the memory */ str = ft_calloc(len + 1, sizeof(char)); if (!str) return (NULL); i = 0; /* we then loop over the string received as parameter from index * start + i and copy each character into our new string index i */ while (i < len) { str[i] = s[start + i]; i++; } /* we finally return the substring */ return (str); } sun-brightdesktopmoon --- # open() & read() | Guide To start this project you must first be able to open a text file. Once opened, we will be able to read it. This can be done using the open() and read() functions. triangle-exclamation PS: If you don't know what it is is a file descriptor (fd), you can check this page before continuing: [🗃️File descriptors (FD)chevron-right](https://42-cursus.gitbook.io/guide/useful-tools/file-descriptors-fd) [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#undefined) ------------------------------------------------------------------------------------------------- [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#open) open () ----------------------------------------------------------------------------------------------------- For the function to work, you must first implement the following library Copy #include This function will allow you to open and access a file. It is prototyped this way: Copy int open (const char* path, int flags [, int mode ]); #### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#path) Path It corresponds to title of the file that you would like to open/create. It also refers to the file’s location. If you are not working in the same directory as the file, you can provide an absolute path that begins with “/” #### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#flags) Flags You have to tell your function what kind of access you want. This is done with flags. Here is the list with the information of each flag: * **O\_RDONLY**: In read-only mode, open the file. * **O\_WRONLY**: In a write-only mode, open the file * **O\_RDWR**: Open the file in reading and write mode * **O\_CREAT**: This flag is applied to create a file if it doesn’t exist in the specified path or directory * **O\_EXCL**: Prevents the file creation if it already exists in the directory or location. #### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#return-value) Return Value The return value of open() is a file descriptor, a small, nonnegative integer that is an index to an entry in the process's table of open file descriptors. If there is an error somewhere, the function will return -1 as a synonym of failure. chevron-rightExample[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#example) There has to be a `text.txt` file so you can open it. For the moment it will not show you anything because the function is only used to open a file. You will have to use an additional function to make it useful. For example the read() function that we will see together now. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#read) read () ----------------------------------------------------------------------------------------------------- The function is prototyped this way: This function attempts to read `nbyte` bytes of data from the object referenced by the descriptor `fildes` into the buffer pointed to by `buf`. The read() function starts at a position given by the pointer associated with `fildes`. At the end, the pointer is incremented by the number of bytes (`nbyte`) actually read. It is well explained in the below video, so I will not get through it once again: It is in french but it has english subtitles ! Now that you know how these two functions work, let's move on to the next step: [understanding static variables](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/static-variables) . A concept that will be used a lot in other projects! See you there 😄 [Previousget\_next\_linechevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line) [NextStatic variableschevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/static-variables) Last updated 1 year ago * [](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#undefined) * [open ()](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#open) * [read ()](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/open-and-read#read) sun-brightdesktopmoon Copy int main() { int fd; fd = open("text.txt", O_RDONLY); } Copy ssize_t read(int fildes, void *buf, size_t nbyte); sun-brightdesktopmoon --- # ft_strjoin | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#subject) Subject Copy FT_STRJOIN (simplified) NAME ft_strjoin -- concatenate 2 strings in a new string SYNOPSIS char *ft_strjoin(const char *s1, const char *s2); DESCRIPTION Allocate (with malloc(3)) and returns a new string resulting from the concatenation of s1 and s2. PARAMETERS s1: prefix string s2: suffix string RETURN VALUES ft_strjoin() returns the new string; NULL if the memory allocation failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#understandable-explanation) Understandable explanation This function works basically the same way as `ft_strlcat` does, but instead of passing it a `destination` `string` that has to be correctly allocated as a parameter, we only pass two `strings` and `ft_strjoin` will allocate the required memory for both of them plus the NUL-terminating character. `s1` will be the first string in the result, `s2` the second one. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#hints) Hints We have to get the length of both strings so we can allocate enough memory for both of them. So that's the first thing to do. Then we can allocate enough memory for both string plus the NUL-terminating character. We then copy `s1` into our newly allocated string, then we copy `s2`, and finally we can set the last character as `NUL`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#commented-solution) Commented solution chevron-rightft\_strjoin[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#ft_strjoin) [Previousft\_substrchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_substr) [Nextft\_strtrimchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin#commented-solution) sun-brightdesktopmoon ft\_strjoin.c Copy #include "libft.h" char *ft_strjoin(const char *s1, const char *s2) { char *res; int i; int j; i = 0; j = 0; /* allocating the required memory */ res = (char *) malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char)); if (!res) return (NULL); /* copying s1 into our res string */ while (s1[i]) res[j++] = s1[i++]; /* we have to reset i to 0, otherwise we won't copy s2 * from the start */ i = 0; /* copying s2 into our res string */ while (s2[i]) res[j++] = s2[i]; /* !! don't forget to NUL-terminate the string !! */ res[j] = 0; /* finallly, we can return the new string */ return (res); } sun-brightdesktopmoon --- # Inception (doing) | Guide This project aims to broaden your knowledge of system administration by using Docker. You will virtualize several Docker images, creating them in your new personal virtual machine. Here, a scheme of the links between the various files. We'll look at them in more detail later. But typically, this is what your inception should look like: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FyvhymcEvTigTobYKwak9%252Fimage.png%3Falt%3Dmedia%26token%3D17454441-90ab-4a27-ac75-76a30d0bc2f3&width=768&dpr=3&quality=100&sign=fd895875&sv=2) Inception overview Let's try to understand each term and see what each project file should contain :) Let's go! [PreviousCPP09 (to-do)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp09-to-do) [NextThe basics (Docker, Images, etc...)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing/the-basics-docker-images-etc...) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Core concepts | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#game-loop) Game loop In most games, one of the core concept is the game loop. What is a game loop ? Well, the game loop is... a loop... but like with more spiciness to it. Seriously, a game loop is the part of the game that handles the logic for updating and rendering the game. It is a continuous loop that typically runs at a fixed rate (such as 60 frames per second) and is responsible for performing the following tasks: 1. Processing input: The game loop retrieves and handles input from the player, such as keyboard or controller input. 2. Updating the game state: The game loop updates the game's data and objects based on the input and any other events that have occurred. 3. Rendering the game: The game loop generates graphics and audio output based on the updated game state. 4. Pausing and sleeping: The game loop may pause or sleep between iterations to maintain a consistent frame rate or to save resources on the device. The game loop is an essential part of a game's architecture, as it determines how the game responds to player input and how it presents itself to the player. With `MiniLibX`, we can do almost everything a game loop does by using the `mlx_loop_hook()` function, but we still have some limitations, like the framerate, we can't (or I didn't find how) limit the framerate of the game. We can't play sounds with it neither. And all the other parts, we can build them ourselves using the different hooks that MLX gives us (key hooks and mouse hooks). ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#rendering-the-game) Rendering the game One way to render the game that is the easiest to build for a simple 2D game like what we have to build for so\_long, is to draw the game as multiple layers each time through the loop. For example, you could have a layer for the background that is the first one you draw. Then you draw the non-moving part of the map (walls, starting position, exit position and collectibles). And finally you draw the player at the player position. By doing so, you basically have a clean canvas every time through the loop, and if something moved between two iterations, you don't have it all on screen. Let's take a look at what the game looks like when I only draw one or the other layer. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FZTrSQn6644CfelTiETen%252FScreen%2520Shot%25202022-12-29%2520at%25202.22.52%2520PM.png%3Falt%3Dmedia%26token%3D912e80de-5bbb-46dc-9e49-159f765c266a&width=768&dpr=3&quality=100&sign=ef00a1b2&sv=2) This is what the game looks like when I only draw the background. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FhGni06yN1w2O9sMA2TFY%252FScreen%2520Shot%25202022-12-29%2520at%25202.30.11%2520PM.png%3Falt%3Dmedia%26token%3D419b89d2-162d-4e5a-bbbd-b8633fafe2e7&width=768&dpr=3&quality=100&sign=8b09bafb&sv=2) This is what the game looks like when I only draw the map. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fa54NtvSSMOaI7au6fcDS%252FScreen%2520Shot%25202022-12-29%2520at%25202.31.02%2520PM.png%3Falt%3Dmedia%26token%3D4ab295a4-60b4-4b3d-a1a4-c0681028b5cb&width=768&dpr=3&quality=100&sign=8c413b45&sv=2) This is what the game looks like when I only draw the player. Now, let's draw all the layers in the correct order. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FbwDj6u1YVNHY0HBs4XHh%252FScreen%2520Shot%25202022-12-29%2520at%25202.21.23%2520PM.png%3Falt%3Dmedia%26token%3Db28fa6aa-e1b9-4ac9-a846-eb8006062aea&width=768&dpr=3&quality=100&sign=99099f44&sv=2) This is what the game looks like when all layers are drawn in the correct order. I won't make a screenshot of every way I can render the game (rendering only the background and player or only the map and player) because I'm sure you can easily make that up in your head what the game would look like in any of these way. With the three layers I have put here, I'm sure you can already see why drawing them in the correct order is useful. You can see that the background draws the "floor" on the complete window, so if you drawn something before drawing the map or the player, everything will be invisible behind it. Now, you might wonder why I draw the background for every game loop iteration. Well, take a look at the following screenshot. Now I won't draw the background each time and make 2 or 3 moves to move the player. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F9ULRFEgYsA3Eb9rAXFDH%252FScreen%2520Shot%25202022-12-29%2520at%25202.38.39%2520PM.png%3Falt%3Dmedia%26token%3D450cd77a-7e7f-4007-bf07-ff5ff6b87ef8&width=768&dpr=3&quality=100&sign=ddb58705&sv=2) This is what happens when I don't draw the background every time through the loop. You can see that the player "multiplied" itself. I mean, it looks like it was multiplied, but actually, it's just that we see what was drawn during the previous loop iterations. We didn't drawn something over the background, and since it's not part of the map, it isn't redrawn every time. The player is drawn during each loop at its current position, but it once was on all these tiles. By not rendering the background in every iterations, everything that was drawn on a tile where the background should be, will not be "overdrawn" and thus will still be visible even though the player moves around. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#update-player-position) Update player position Since this is a video game that we are building, there surely will be a player or at least a character controlled (directly or indirectly) by the person playing your game. The starting position for the player is known and can't be directly changed since it comes from the map that has to be parsed and checked by your program. That let's draw the player at the correct starting position but how could we update where the player should be showed on the window ? Well, let's take an example map and how this could be working. As we can see here, the starting point of the player, as coordinates (y; x) is (3; 1). That means, the first time through the game loop, we can draw the player at position (3; 1), but now, the player presses the right arrow key, the player should move to the right, right ? How can you change where the player is drawn ? That's actually pretty easy. You can simply update the player position, we had (3; 1) the first time through the loop, when the player presses the right arrow key, we have to add 1 to the `x` coordinate of the player position. If we do this, we have now (3; 2). The next time through the game loop, the player will be draw at the "player position" coordinates, that is now (3; 2). To update the player position in other direction, we have to change the coordinates correctly depending on what key is pressed. Here's an example: I think that with these concepts you can already go a pretty long way in so\_long, if something is missing, don't hesitate to tell us and we'll update this page. If you read everything until here, Iet's move to the next section and start actually building the thing. [PreviousUnderstand so\_longchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/understand-so_long) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing) Last updated 1 year ago * [Game loop](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#game-loop) * [Rendering the game](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#rendering-the-game) * [Update player position](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts#update-player-position) sun-brightdesktopmoon Copy 1111111111111 10010000000C1 1000011111001 1P0011E0C0001 1111111111111 Copy int key_handler(int keycode, t_vars *vars) { if (keycode == KEY_ARROW_RIGHT) vars->player.pos.x += 1; else if (keycode == KEY_ARROW_LEFT) vars->player.pos.x -= 1; else if (keycode == KEY_ARROW_UP) vars->player.pos.y -= 1; else if (keycode == KEY_ARROW_DOWN) vars->player.pos.y += 1; return (0); } sun-brightdesktopmoon --- # Variadic functions | Guide The functions you have used and created so far in your course had fixed arguments. There could be several, but you always knew in advance what arguments you would need. For example strlen only takes a string as input `(int ft_strlen(char *str))` and split takes two elements as input `(**ft_split(char const *s, char c))`. You get the idea. A **variadic function** is a function which accepts a **variable number of arguments**. It is characterized by the **"..."** in a function. Copy int ft_printf(const char *format, ...); // const char *format is the mandatory argument of printf circle-exclamation The variadic function must have at least one **mandatory argument.** There is no minimum for the number of variable arguments. When someone calls the printf function, we don't know in advance how many elements the person wants to display. In other words, we don't know how many times the format specifier will be used. Copy printf("hello my name is %s and i am %d old\n", "laura", 23); In the above case, the function takes two other arguments, in addition to the initial string. If you knew in advance how many arguments you were using and of what type, the function could be rewritten in this way: Copy int ft_printf(const char *format, char *string, int age); Thankfully the C language is well done. There is no need to rewrite the printf function every time you change the number of arguments in input. You will just have to include the "stdarg" library which will allow you to use a new type of variable, `**va_list**`_,_ and 3 very useful _macros_: `**va_start**`**,** `**va_arg**` & `**va_end**` Copy #include Let's take a closer look at how to use them [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_list-va_start-va_end-and-va_arg) va\_list, va\_start, va\_end & va\_arg ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_list-new-object-type) `va_list` \- new object type `va_list` is an **object type** suitable for holding the information needed by the macros `va_start`, `va_copy,` `va_arg`, and `va_end` (that you will understand in a few minutes). In other words, it is a list that will contain all the dynamic arguments. To create a variable of this type, you will have to do it the same way as any other variable. This will create the list of dynamic arguments which can be illustrated as follows ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FJQE4IiMnRajaSxOXSZfm%252Fva_list.PNG%3Falt%3Dmedia%26token%3Db490a958-c9ed-4ddd-8025-b78e39a99be8&width=768&dpr=3&quality=100&sign=fd4279c6&sv=2) In this example, the printf function takes 2 extra arguments, in addition to the mandatory argument. These two arguments are the variable arguments and will be stored in the previously created variable of type va_list,_ thanks to `va_start`. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_start-function-macro) `**va_start**` **- function macro** The macro `va_start` function will somehow initialize everything, before we start moving through our variable argument list (va\_list). You have to write it like that: * `var` is a variable of type arg\_list (args for us) * `parameterN` is the named parameter preceding the first dynamic parameter (in our case, with printf, it would be the initial string) - in other words, **it's the mandatory argument** Its purpose is to set the stage and define which elements will be stable and which will vary. This is when your va\_list variable will have all the elements in the table. circle-exclamation `va_start` must be called before any use of `va_arg - otherwise your va_list variable/table will be empty.` ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_arg-function-macro) `**va_arg**` **- function macro** Now that everything is ready, you can start using and playing with your variable arguments. This can be done with va\_arg. This macro allows access to the arguments of the variadic function. Each time `va_arg` is called, you move to the next argument. `va_arg` will take as argument first the list of dynamic arguments we had defined at the very beginning (va\_list object) and **the type** of the variable of the next argument. Let's go back to our example ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FlmGPVuZpbLQdK3grc8gQ%252Fva_list.PNG%3Falt%3Dmedia%26token%3D9f9980e1-5f3a-4feb-8a9d-18cde5d84217&width=768&dpr=3&quality=100&sign=ecbf3bba&sv=2) The length of our variable argument list (args) is 2. There is a string argument in first position and an int argument in second position. If you want to access the first argument, you will have to call `va_arg` once and specify the type of the argument. In this case, the first argument is a string, that will be defined by a pointer. If you want to access the second argument, you do the same thing. But this time the type of the argument is an "int". Obviously, this is just a theoretical example so that you can understand how va\_arg works. In practice, since we don't know in advance how many arguments the function will take, you can imagine that you will have to create conditions for each specified format. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_end-function-macro) `**va_end**` **- function macro** Once you have finished your program, don't forget to clean up the object you initialized by calling va\_start. `va_end` can modify the object, which was called "args" in our previous example**,** so that it is no longer usable. `va_end()` will free the allocated memory. Now that you have the basics and have understood the most complicated part (aka the variadic functions (scary huh ?)) you can try to create your own printf : the legendary ft\_printf. Let's do it together step by step. [Previousft\_printfchevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/building-the-thing) Last updated 1 year ago * [va\_list, va\_start, va\_end & va\_arg](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_list-va_start-va_end-and-va_arg) * [va\_list - new object type](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_list-new-object-type) * [va\_start - function macro](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_start-function-macro) * [va\_arg - function macro](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_arg-function-macro) * [va\_end - function macro](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf/variadic-functions#va_end-function-macro) sun-brightdesktopmoon Copy va_list any_name_you_want; // we will call it args for the next example: va_list args; Copy va_start( va_list var, parameterN ); // in our example, it would be: va_start( args, format); Copy va_arg( va_list var, type_of_the_variable ) Copy // access the first argument (type "string") va_arg( args, char * ) // -> "Laura" // access the second argument (type "int") va_arg( args, int ) // -> 23 Copy va_end( va_list var ); // and in our example: va_end (args); sun-brightdesktopmoon --- # ft_transcendence (to-do) | Guide No more C! No more C++! This project is about doing something you’ve never done before. Remind yourself the beginning of your journey in computer science. Look at you now. Time to shine! [Previouswebserv (to-do)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/webserv-to-do) [NextExam Rank 02chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_putendl_fd | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#subject) Subject Copy FT_PUTENDL_FD (simplified) NAME ft_putendl_fd -- write a string on a specified file descriptor, follow by a newline SYNOPSIS void ft_putendl_fd(char *s, int fd); DESCRIPTION ft_putendl_fd() writes the string s, followed by a newline, on the file descriptor fd PARAMETERS s: string to write fd: the file descriptor on which to write RETURN VALUES ft_putendl_fd() does not return anything AUTHORIZED EXTERNAL FUNCTIONS write(2) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#understandable-explanation) Understandable explanation This one is pretty straight forward, if you already built the `ft_putstr_fd()` function, you can work it out by yourself I think. It works the same way, it just adds a `newline` character at the end. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#hints) Hints As said above, take a look at how you did `ft_putstr_fd()`, it should be fairly easy from there. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#commented-solution) Commented solution chevron-rightft\_putendl\_fd[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#ft_putendl_fd) [Previousft\_putstr\_fdchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd) [Nextft\_putnbr\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd#commented-solution) sun-brightdesktopmoon ft\_putendl\_fd.c Copy #include "libft.h" void ft_putendl_fd(char *str, int fd) { int i; i = 0; while (str[i]) { write(fd, &str[i], 1); i++; } write(fd, "\n", 1); } sun-brightdesktopmoon --- # FdF | Guide Well, if you are here it means that you have survived GNL and maybe already push swap... FdF is much less bad than these two projects. You will have to go back to math, but nothing too complicated, don't worry ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf#goal) Goal chevron-rightProject-specific guidelines[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf#project-specific-guidelines) * The result should be displayed using an **isometric projection**. * Your program must display an image in a window. * The management of the window should remain smooth (change the window, minimize it, etc.). * Pressing the ESC key should close the window and exit the program cleanly. * Clicking on the cross at the top of the window should close the window and exit the program cleanly. * Using the MiniLibX images is mandatory. Of course! FdF is the abbreviation of "Fil de Fer", which means "Wireframe" in French. The FdF project is one of the first graphics projects. The goal of the FdF project is to create a software that can read a file containing information about a 3D object and display it as a wireframe model on the screen. You have to go from a representation like this: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F7ZeVEsb8pH6s0zQxVtts%252Fimage.png%3Falt%3Dmedia%26token%3Df19cf360-14c8-439c-8507-d6fd015e62ca&width=768&dpr=3&quality=100&sign=834ad46d&sv=2) 2D representation of the "42.fdf" map Where the rows represent the x-axis, the columns the y-axis and the values the z-axis (the altitude). To a graphic representation like this: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FJ4vbPgw3Xg9yFsjwt9iD%252Fimage.png%3Falt%3Dmedia%26token%3Dab1a2a6e-c398-41c8-afdd-2a2b85b42f89&width=768&dpr=3&quality=100&sign=d830112a&sv=2) 3D representation of the "42.fdf" map The subject is simple and clear. In practice it is a bit more complicated than that because many new concepts are introduced. But by separating each step and looking at one element after the other, you will be able to do this project very easily. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf#visual-final-example) Visual Final Example To give you an idea, here is what the final project should look like: Well, the guy is a genius and he did more things than requested in the project - but you get the general idea :-) This project will have more pages than the others. There will be a theoretical part about the new things you have to learn in this project (and an explanation of all the new functions), a mathematical part to understand the transformation process and a practical part, where you will code FdF thanks to everything you will have learned and to checklists we will define. Okay, let's get to the heart of the matter now [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing) [NextUnderstand FdFchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf) Last updated 2 years ago * [Goal](https://42-cursus.gitbook.io/guide/2-rank-02/fdf#goal) * [Visual Final Example](https://42-cursus.gitbook.io/guide/2-rank-02/fdf#visual-final-example) sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand Philosophers | Guide circle-exclamation We didn't do the bonuses so we will not explain anything about it. I'll let you do some research yourself ;) ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-process) What is a process ? > A process is a program that is running on your computer. This can be anything from a small background task, such as a spell-checker or system events handler to a full-blown application like Internet Explorer or Microsoft Word. All processes are composed of one or more [threadsarrow-up-right](https://techterms.com/definition/thread) > . If you want a more precise example of what a process is, you can click [\[here\]arrow-up-right](https://42-cursus.gitbook.io/guide/rank-02/minitalk/understand-minitalk#processes-and-signals) . Laura created and showed a good example. > Since most [operating systemsarrow-up-right](https://techterms.com/definition/operating_system) > have many background tasks running, your computer is likely to have many more processes running than actual programs. For example, you may only have three programs running, but there may be twenty active processes. You can view active processes in Windows by opening the Task Manager (press Ctrl-Alt-Delete and click Task Manager). On a Mac, you can see active processes by opening Activity Monitor (in the Applications→Utilities folder). Source : [techterms.comarrow-up-right](https://techterms.com/definition/process) ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-thread) What is a thread ? > What do a t-shirt and a computer program have in common? They are both composed of many threads! While the threads in a t-shirt hold the shirt together, the threads of a computer program allow the program to execute sequential actions or many actions at once. Each thread in a program identifies a process that runs when the program asks it to (unlike when you ask your roommate to do the dishes). > > Threads are typically given a certain priority, meaning some threads take precedence over others. Once the CPU is finished processing one thread, it can run the next thread waiting in line. However, it's not like the thread has to wait in line at the checkout counter at Target the Saturday before Christmas. Threads seldom have to wait more than a few milliseconds before they run. Computer programs that implement "multi-threading" can execute multiple threads at once. Most modern operating systems support multi-threading at the system level, meaning when one program tries to take up all your CPU resources, you can still switch to other programs and force the CPU-hogging program to share the processor a little bit. Source: [techterms.comarrow-up-right](https://techterms.com/definition/thread) ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#differences-between-threads-and-processes) Differences between threads and processes Both processes and threads are independent sequences of execution. The typical difference is that threads (of the same process) run in a shared memory space, while processes run in separate memory spaces. (source: [stackoverflowarrow-up-right](https://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread) ) Here under are some points that I noted during my research : #### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#process) Process * Can have multiple threads * When using fork(), duplicates everything * This means a variable is just copied, if we modify the variable in one process it won't be modified in the other one #### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#threads) Threads * share memory space * if I declare a variable somewhere, and modify it inside of a thread, it will be changed for every other threads as well * can run in what's called a "memory race" * since the memory is shared between threads, if multiple threads try to access the same variable at the same time, it's called a "memory race" since the "fastest" thread will modify the variable value, and then the other one will. But the value of the first modification could have useful somewhere. * we have to protect our program against "memory race", like we do for "memory leaks" ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-mutex-pthread_mutex) What is a mutex ? (pthread\_mutex) A mutex is basically a lock. We can lock a variable so that only one thread can access the variable at a time. When the first thread finished its operation on the variable, we unlock the mutex so that the other thread can access the variable. [PreviousPhilosopherschevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers) [NextFunctions usedchevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used) Last updated 2 years ago * [What is a process ?](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-process) * [What is a thread ?](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-thread) * [Differences between threads and processes](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#differences-between-threads-and-processes) * [What is a mutex ? (pthread\_mutex)](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers#what-is-a-mutex-pthread_mutex) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_striteri | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#subject) Subject Copy FT_STRITERI (simplified) NAME ft_striteri -- apply a function to each character of a string (index specified) SYNOPSIS void ft_striteri(char *s, void (*f)(unsigned int, char*)); DESCRIPTION Apply the function 'f' to each characters of the string 's', passing its index as a first parameter. Each character is transmitted by address to 'f' so it can be modified if necessary. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#understandable-explanation) Understandable explanation `ft_striteri` works the same way as `ft_strmapi` does, take a look at the explanation for `ft_strmapi` and then come back here. The difference between `ft_striteri` and `ft_strmapi` is that `ft_striteri` doesn't return anything and works directly on the original string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#hints) Hints This functions takes two parameters, the first one is a string, and the second one is a function. What `ft_striteri` does is apply the function `f` to every character of the string `s`. It passes the index of the character in the string, and a pointer to the character to the function `f`. The function `f` directly modifies the value of the character in the original string. At the end, we don't need to return anything but the original string will have been modified. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#commented-solution) Commented solution chevron-rightft\_striteri[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#ft_striteri) [Previousft\_strmapichevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi) [Nextft\_putchar\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri#commented-solution) sun-brightdesktopmoon ft\_striteri.c Copy #include "libft.h" void ft_striteri(char *s, void (*f)(unsigned int, char*)) { unsigned int i; i = 0; /* looping over the whole original string */ while (s[i]) { /* apply the function f to the character at index i * passing i and the address to s[i] as parameter to f * f will update the original string directly */ (*f)(i, &s[i]); i++; } } sun-brightdesktopmoon --- # CPP06 (to-do) | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp06-to-do#main-topics) Main topics Copy C++ casts [PreviousCPP05chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp05) [NextCPP07chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand minitalk | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#goal) Goal chevron-rightProject-specific guidelines (2023)[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#project-specific-guidelines-2023) You must create a communication program in the form of a client and a server. * The server must be started first. After its launch, it has to print its PID. * The client takes two parameters: 1) The server PID 2) The string to send. * The client must send the string passed as a parameter to the server. Once the string has been received, the server must print it. * The server has to display the string pretty quickly. Quickly means that if you think it takes too long, then it is probably too long. * Your server should be able to receive strings from several clients in a row without needing to restart. * The communication between your client and your server has to be done only using UNIX signals. * You can only use these two signals: SIGUSR1 and SIGUSR2. The goal of the Minitalk project is to develop a simple program that allows processes (= programs running on a computer) to communicate with each other using a communication protocol called "minitalk". It corresponds to the protocol that you need to code. The minitalk communication protocol involves sending messages between two processes using a series of signals over a single wire. * One process, called the "speaker/client" sends the message by transmitting a series of signals over the wire. * The other process, called the "listener/server" receives the message by interpreting the series of signals as a message. circle-info **Signals are a form of communication between processes** used by Unix-like systems (e.g. MacOS or Linux) and those respecting the POSIX standards. **Signals can be defined as a message**, an event or an interrupt. When a process receives a signal, the process will stop what its doing and **take some action**. In the context of the Minitalk project, signals are used to transmit messages between processes using the minitalk communication protocol. I am a visual person, so I tried to make this diagram for you to understand better: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F5eY61q1QT9MHUx2Zxf7g%252Fminitalk_scheme.png%3Falt%3Dmedia%26token%3D22a960bd-d30e-4e73-a4e7-a683b9c4d931&width=768&dpr=3&quality=100&sign=af87f37b&sv=2) minitalk explanatory scheme As we can see, we have a client that wants to send a message to the server. The "Hello" (message) cannot be sent directly to the server. The client has to encrypt the message and the server has to decrypt/interpret it before it can be displayed. I'll keep it general here and go into more detail in the "[Building the thing](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing) " section. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#processes-and-signals) Processes & signals circle-info We are going to go a little further than what is asked in the subject, but it is to better understand later what you do. **Processes and signals are the most important terms to know in this project.** I've already explained a bit about them above, but you may not have fully understood them yet - let's take another simple example to understand these new concepts. As i said before, in computer science, a signal is a message that is sent to a process to indicate a particular event has occurred or to request a particular action to be taken. A process is a program that is being executed by the computer. Let's take a simple example: Imagine you have a program that is running on your computer. This program is Google Chrome running in the background on your computer. When you have multiple windows open on your browser, you have multiple programs running. These programs are called processes. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FzxbAfE6S0J8cgzWYT6dU%252Fimage.png%3Falt%3Dmedia%26token%3D90f1ac62-1ca3-4c99-98d5-fe33335dd18e&width=768&dpr=3&quality=100&sign=b1d9cd5f&sv=2) Now, suppose that you want to stop these program. You can do this by simply closing the browser window in question. Easy. Or by sending a signal to the process. **Remember: a signal is just telling a process to do a certain thing!** Here, we want to close the windows. That will be the signal that we want to send to the processes. For this, you might use the "kill" command in a terminal window to send a signal to the processes. This signal tells the process to terminate itself. So in this example, the signal (the "kill" command) is used to request a particular action (termination of the process) to be taken. To send a signal to a certain process **you need the PID** of it. They will be useful, because that's how you will know which signal to send to which process. It's like a computerized version of our passports. Example on how to dit it: `kill ` If you use the above command you will have to kill one process after the other. As they are all part of Chrome, you could also use a single command instead, which will close all running programs (processes) related to chrome. `killall chrome` chevron-rightTo go a bit bit further[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#to-go-a-bit-bit-further) If you are curious, you can find all the "Google Chrome" programs currently running on your computer by typing this command: `ps -Af | grep chrome` It will pull up a list of all Chrome processes. A bit like that: _Note: if you did not open google chrome but you still see a line appearing, it is by the simple fact of having called it with the command above (grep chrome)_ The second column will contain the process identifier (PID) of the processes. So 2706, 2713 or 2720, all correspond to the PID of a certain process. Well, I hope you now have a better understanding of the basic concept! Now let's move on to the last theoretical part. To achieve this project, you will have to understand and use [new functions](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used) that allow to manage these computer signals: signal(), sigemptyset(), sigaddset(), sigaction(), kill(), pause() and sleep(). [Previousminitalkchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk) [NextFunctions usedchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used) Last updated 1 year ago * [Goal](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#goal) * [Processes & signals](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk#processes-and-signals) sun-brightdesktopmoon Copy 1000 2706 1 2 23:01 ? 00:00:52 /usr/bin/google-chrome-stable 1000 2713 2706 0 23:01 ? 00:00:00 /usr/bin/google-chrome-stable 1000 2714 2706 0 23:01 ? 00:00:00 /opt/google/chrome/chrome-sandbox /opt/google/chrome/chrome --type=zygote 1000 2715 2714 0 23:01 ? 00:00:00 /opt/google/chrome/chrome --type=zygote 1000 2719 2715 0 23:01 ? 00:00:00 /opt/google/chrome/nacl_helper 1000 2720 2715 0 23:01 ? 00:00:00 /opt/google/chrome/chrome --type=zygote 1000 2839 2706 0 23:01 ? 00:00:08 /opt/google/chrome/chrome --type=gpu-process --channel=2706.3.250838429 --supports-dual-gpus=false --gpu-driver-bug-workarounds=0,1,27 --disable-accelerated-video-decode --gpu-vendor-id=0x1002 --gpu-device-id=0x6760 --gpu-driver-vendor=ATI / AMD --gpu-driver-version=13.30 1000 2843 2839 0 23:01 ? 00:00:00 /opt/google/chrome/chrome --type=gpu-process --channel=2706.3.250838429 --supports-dual-gpus=false --gpu-driver-bug-workarounds=0,1,27 --disable-accelerated-video-decode --gpu-vendor-id=0x1002 --gpu-device-id=0x6760 --gpu-driver-vendor=ATI / AMD --gpu-driver-version=13.30 1000 3038 2720 1 23:08 ? 00:00:28 /opt/google/chrome/chrome --type=renderer --lang=en-US --force-[...very long options list] 1000 4505 4441 0 23:40 pts/0 00:00:00 grep --color=auto chromebash sun-brightdesktopmoon --- # Graphics programming | Guide I had a lot of difficulty at the beginning to distinguish between all the terms I had just found on the web. This new chapter is a big one. Let's try to get some practice on this brand new chapter which is graphic programming (it's really fun, trust me :-) ) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#display-vs-window-vs-image) Display VS Window VS Image When you start coding, the first thing you'll do is initialize your workspace. There are these three terms that I find very similar and I couldn't tell them apart, but in the end they are very different: #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#display) **Display** A display is something that shows visual information. In the context of graphical programming, it refers to the physical device that displays the graphical user interface. For example, when you are using a computer, the display could be a monitor or a TV connected to the computer via HDMI. #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#window) **Window** A window is a graphical element that **represents a rectangular area on the display**. It is used to display content, such as text, images, or videos. For example, a window might contain a text editor, a web browser, or a video player. #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#image) **Image** An image is a **two-dimensional array of pixels** that can be displayed on the display. It can be a static image, such as a photograph, or a dynamic image, such as a video. In graphical programming, images are often used to display graphical elements, such as icons, backgrounds, or visual effects. They can be displayed by themselves or as part of a window. Your displays, windows, and images can have several different sizes (defined in pixels). It's up to you to define which size best fits what you do and what you need. Here is a small diagram to better visualize: \[insert scheme\] chevron-rightExample in C[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#example-in-c) Before starting to do graphic programming you should always think about initiating a display and one or more windows and images. Copy int main(void) { void *mlx; //display void *mlx_win; //window t_data image; //image mlx = mlx_init(); //display init mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello world!"); //window init image.img = mlx_new_image(mlx, 1920, 1080); //image init } ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#interacting-with-your-program-with-hooks) Interacting with your program (with hooks) When you work on a graphic project, you will be able to interact with the window you are working on. You can for example close a window, zoom in/out and many other things. This can be done thanks to a thing called "hook". A **hook** in computer science is a way to intercept and modify the behavior of a function or system call. It is often used to add additional functionality or to customize the behavior of a program or operating system. chevron-rightSimple example of a hook[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#simple-example-of-a-hook) Imagine that you have a program that displays a message on the screen every time you press a certain key on the keyboard. You might want to add some additional behavior to this program, such as changing the color of the message or playing a sound every time the key is pressed. To do this, you could "hook" the function that handles the key press events. When the key is pressed, your hook function would intercept the event and perform the additional behavior you want, such as changing the color of the message or playing a sound. Then, it would pass the event along to the original function so that the message can be displayed as usual. Here is some pseudocode that shows how this might work: This concept will be really userful for the rest of the project. [PreviousUnderstand FdFchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing) Last updated 2 years ago * [Display VS Window VS Image](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#display-vs-window-vs-image) * [Interacting with your program (with hooks)](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming#interacting-with-your-program-with-hooks) sun-brightdesktopmoon Copy //Original function that handles key press events void OnKeyPress(Key key) { // Display a message DisplayMessage("You pressed the key: " + key); } // Hook function that intercepts key press events void Hooked_OnKeyPress(Key key) { // Perform additional behavior ChangeMessageColor(Color.Red); PlaySound("beep.wav"); // Pass the event along to the original function OnKeyPress(key); } // Hook the OnKeyPress function void HookOnKeyPress() { // Replace the OnKeyPress function with our hook function OnKeyPress = Hooked_OnKeyPress; } // Main program loop void Main() { // Hook the OnKeyPress function HookOnKeyPress(); // Wait for key press events while (true) { Key key = WaitForKeyPress(); OnKeyPress(key); } } sun-brightdesktopmoon --- # Level 1 & 2 | Guide Let's go level by level and try to ask ourselves the right questions to solve each exercise. PS: Don't check the answers immediately. Otherwise you will not learn anything and you'll have a hard time during your evaluation [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#id-0.1-how-to-find-the-ip-from-one-mask-and-one-ip) 0.1 How to find the IP _(from one mask & one IP)_ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Find the IP of one machine (Interface 2) using its mask and the IP of the other machine (Interface 1). * Convert the IP address and subnet mask to binary. Interface 1 IP address: 192.168.25.222 -> 11000000.10101000.00011001.11011110 Interface 2 subnet mask: 255.255.255.224 -> 11111111.11111111.11111111.11100000 * Perform the bitwise "AND" operation between each corresponding bit of the IP address and the subnet mask. 11000000.10101000.00011001.11011110 11111111.11111111.11111111.11100000 = 11000000.10101000.00011001.11000000 * Convert the binary result back to decimal notation. \--> Thus, the IP address of interface 2 could be 192.168.25.192, assuming the provided subnet mask is applicable to the network configuration in this specific context. Now, regarding the address range, with a subnet mask of 255.255.255.224 (or /27), [**the available address range is 30 addresses**arrow-up-right](https://42-cursus.gitbook.io/guide/rank-04/netpractice/tcp-ic-and-masks#masks-subnet-masks) . In this case, the address range would be 192.168.25.192 to 192.168.25.223. It's important to note that every IP address in this range is considered valid for interface 2, as long as it's not already in use by another interface or device on the network. So, if you mark the response 192.168.25.194, this would also be a valid IP address for interface 2, as it's within the range of addresses available with the given subnet mask. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#id-0.2-how-to-find-a-subnet-mask-from-one-ip-and-one-mask) 0.2 How to find a subnet mask (from one IP and one mask) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To find the subnet mask of interface 2 from the IP address of interface 1 and the IP address of interface 2, you can follow these steps: * Convert both IP addresses to binary. Interface 1 IP address: 192.168.25.222 -> 11000000.10101000.00011001.11011110 Interface 2 IP address: 192.168.25.192 -> 11000000.10101000.00011001.11000000 * Compare the bits of the IP address of interface 1 and the IP address of interface 2 IF1: 11000000.10101000.00011001.11011110 IF2: 11000000.10101000.00011001.11000000 Start with the most significant bit (from left to right) and compare each corresponding bit of the two IP addresses. Find the first instance where the bits differ between the two IP addresses. From this point onwards, all subsequent bits must be set to 0 in the subnet mask. \= 11111111.11111111.11111111.00000000 In this case, the longest sequence of consecutive 1 bits is "24 bits". * Convert this sequence of bits to decimal notation. Interface 2 subnet mask: 255.255.255.0 Thus, the subnet mask of interface 2 would be 255.255.255.0, assuming the provided IP addresses correspond to a valid network configuration in this specific context. Let's put what we've just learned into practice :) [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#level-1-simple-case) Level 1 : Simple case -------------------------------------------------------------------------------------------------------------------------------- The aim is to connect one computer with another, twice. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FTaixjt7qYSjd1K5hVH1O%252Fimage.png%3Falt%3Dmedia%26token%3D33ad232a-8525-4c1f-8e3c-be7bb982f955&width=768&dpr=3&quality=100&sign=7f7214f1&sv=2) NetPractice : Level 1 Here we have two separate networks, each consisting of two computers. Try to find their IP using the first method that I told you. To find the IP address of interface A1, you need to use the mask of A1 and the IP address of B1. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#level-2-masks-are-a-bit-modified) Level 2 : Masks are a bit modified ---------------------------------------------------------------------------------------------------------------------------------------------------------- ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F1SENViEfXDOqWQxEVKgz%252Fimage.png%3Falt%3Dmedia%26token%3D66211185-3370-4e64-9038-7f9f54e6d5fa&width=768&dpr=3&quality=100&sign=9002de7e&sv=2) Level 1 Example Here we have two separate networks, each consisting of two computers. [PreviousTheorychevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory) [NextMiniRTchevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/minirt) Last updated 1 year ago * [0.1 How to find the IP (from one mask & one IP)](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#id-0.1-how-to-find-the-ip-from-one-mask-and-one-ip) * [0.2 How to find a subnet mask (from one IP and one mask)](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#id-0.2-how-to-find-a-subnet-mask-from-one-ip-and-one-mask) * [Level 1 : Simple case](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#level-1-simple-case) * [Level 2 : Masks are a bit modified](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2#level-2-masks-are-a-bit-modified) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_strmapi | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#subject) Subject Copy FT_STRMAPI() (simplified) NAME ft_strmapi -- apply a function to each character of a string SYNOPSIS char *ft_strmapi(const char *s, char (*f)(unsigned int, char)); DESCRIPTION Apply the function 'f' to each characters in the string 's' to create a new string (with malloc(3)) resulting of the successive applications of 'f'. PARAMETERS s: string over which to iterate f: function to apply to each character RETURN VALUES ft_strmapi() returns a new string resulting of the successive applications of 'f'; NULL if the memory allocations failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#understandable-explanation) Understandable explanation This functions takes two parameters, the first one is a string, and the second one is a function. What `ft_strmapi` does is apply the function `f` to every character of the string `s`. It passes the index of the character in the string, and the character to the function `f`. The result of the function `f` is placed in the new string at index `i`. At the end, we return the new string resulting of the application of `f` on every character of the string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#hints) Hints First, we have to allocate enough memory for the whole string plus one for the NUL-terminating character. Then we can loop over the string `s`, and call the function `f` on each character of `s`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#commented-solution) Commented solution chevron-rightft\_strmapi[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#ft_strmapi) [Previousft\_itoachevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa) [Nextft\_striterichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_striteri) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi#commented-solution) sun-brightdesktopmoon ft\_strmapi.c Copy #include "libft.h" char *ft_strmapi(const char *s, char (*f)(unsigned int, char)) { unsigned int i; char *res; /* allocating the memory for the new string */ res = malloc((ft_strlen(s) + 1) * sizeof(char)); if (!res) return (NULL); i = 0; /* looping over the whole string s */ while (i < ft_strlen(s)) { /* applying the function f to each character of s * and storing the result in the new string res */ res[i] = (*f)(i, s[i]); i++; } /* setting the NUL-terminating character */ res[i] = 0; /* finally, we return res */ return (res); } sun-brightdesktopmoon --- # ft_itoa | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#subject) Subject Copy FT_ITOA (simplified) NAME ft_itoa -- convert an int to a string SYNOPSIS char *ft_itoa(int n); DESCRIPTION Allocate (with malloc(3)) and returns a string representing n. Negative numbers must be handled. PARAMETERS n: int to convert RETURN VALUES ft_itoa() returns the string representing n; NULL if the memory allocation failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#understandable-explanation) Understandable explanation The `ft_itoa` function does the opposite work of `ft_atoi`, converting a number to a string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#hints) Hints Since we need to allocate some memory for the new string created from the int value we received, we have to count how much memory we have to allocate. We have a function that count the length of a string, so for this one we'll build one counting the number of characters representing a number. circle-exclamation Remember that `-` is also a character for negative numbers, so don't forget to count it when counting. Once we know the number of characters representing the value we received, we need to allocate enough memory for it plus the NUL-terminating character. Once that is done, we can start converting our number to string, the easiest way to do it is to go from right to left, since we know how much character the string will be, and we can use the modulo operator to get the last character of the number. And then we can simply divide the number by ten to remove the last character from it. Remember this : Since both values are integers, the division will effectuated as an integer division, meaning that there's no remainder nor floating point values in the result, that's why we get 12 by dividing 124 by 10. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#commented-solution) Commented solution chevron-rightft\_itoa[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#ft_itoa) [Previousft\_splitchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split) [Nextft\_strmapichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strmapi) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa#commented-solution) sun-brightdesktopmoon Copy int a = 124; int b = 10; int c = a / b; printf("%d\n", c); => 12 ft\_itoa.c Copy #include "libft.h" static int int_len(long nbr); static char *pre_conv(int len); char *ft_itoa(int n) { int len; int i; char *result; long nbr; /* here I convert the int n received as parameter to a long * this is only done so that INT_MIN and INT_MAX are not a problem * and I can treat them the exact same way as all other numbers */ nbr = n; /* getting the length of the number */ len = int_len(nbr); /* allocating the string with the correct size and * settings result[0] = '0' */ result = pre_conv(len); if (!result) return (NULL); /* if the number is less than 0, we do the same thing as in the * int_len function, we set the number equals to minus itselft. if (nbr < 0) nbr = -nbr; /* we then set i = len - 1, len take into account the NUL-terminating * character and we don't want to overwrite ti. i = len - 1; /* then we can make the conversion from int to character */ while (nbr != 0) { result[i] = ((nbr % 10) + 48); nbr = nbr / 10; i--; } /* if the original number was negative, we set the first character equals to null/ 0;8/ if (n < 0) result[0] = '-'; result[len] = 0; /* At the very end, we can return the string we just craeated \* return (result); } static char *pre_conv(int len) { char *tmp; /* we allocate enough memory for len + 1 character so we * don't skip the NUL-terminating character */ tmp = malloc((len + 1) * sizeof(char)); if (!tmp) return (NULL); /* here I set the index 0 of the newly allocated string to be * character 0. * I do this here, because in the ft_itoa function, if the number * is 0, it will result in no condition working, and if I don't * set the first character working, we would have whatever value * was in memory at tmp[0], maybe the character 0, but most often * this will be some random junk value */ tmp[0] = '0'; return (tmp); } static int_len(long nbr) { int count; count = 0; /* the number is less than 0, we add one to the count to take * into account the - we'll have to add at the end * and we set the number equal to minus itself so it becomes * positive */ if (nbr < 0) { count++; nbr = -nbr; } /* if the number equals 0, we have to add 1 to the count * you could skip this check by starting the count variable at 1 * instead of 0 */ if (nbr == 0) count++; /* if we get to this point, the number will be different than 0 * we then divide the number by ten and add 1 to the count each * time through the loop */ while (nbr != 0) { nbr /= 10; count++; } /* we can finally return the count that is how much characters are * needed to represent this number as string */ return (count); } sun-brightdesktopmoon --- # Bonus functions | Guide [ft\_lstnewchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew) [ft\_lstadd\_frontchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front) [ft\_lstsizechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize) [ft\_lstlastchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast) [ft\_lstadd\_backchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back) [ft\_lstdelonechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone) [ft\_lstclearchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear) [ft\_lstiterchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter) [ft\_lstmapchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap) [Previousft\_putnbr\_fdchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd) [Nextft\_lstnewchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_lstsize | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#subject) Subject Copy FT_LSTSIZE (simplified) NAME ft_lstsize -- returns the number of element in the list SYNOPSIS int *ft_lstsize(t_list *lst); DESCRIPTION Count the number of elements of the list PARAMETERS lst: start of the list RETURN VALUES The size of the list AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#understandable-explanation) Understandable explanation I think the subject is clear on what this function does, we have to return the number of element of the list. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#commented-solution) Commented solution chevron-rightft\_lstsize[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#ft_lstsize) [Previousft\_lstadd\_frontchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front) [Nextft\_lstlastchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize#commented-solution) sun-brightdesktopmoon Copy /* loop over the list */ /* return the count */ ft\_lstsize.c Copy #include "libft.h" int ft_lstsize(t_list *lst) { /* I used a tmp variable so that we don't modify the * existing list */ t_list *tmp; int i; tmp = lst; i = 0; /* we loop as long as tmp is not equal to null * since the last element's next point to null * we will be iterating over all the elements of the list */ while (tmp) { /* set the tmp to be its 'next' element */ tmp = tmp->next; i++; } /* returning the count */ return (i); } sun-brightdesktopmoon --- # ft_lstadd_front | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#subject) Subject Copy FT_LSTADD_FRONT (simplified) NAME ft_lstadd_front -- Adds a new element at the front of the list SYNOPSIS void ft_lstadd_front(t_list **lst, t_list *new); DESCRIPTION Add the 'new' element at the front of the list PARAMETERS lst: pointer address to the first element of the list new: pointer address of the new element to add to the list RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#understandable-explanation) Understandable explanation This function lets us add a new element to the front of an existing list. We receive the new element and the existing list. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#commented-solution) Commented solution chevron-rightft\_lstadd\_front[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#ft_lstadd_front) [Previousft\_lstnewchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew) [Nextft\_lstsizechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front#commented-solution) sun-brightdesktopmoon ft\_lstadd\_front Copy /* set the new element's next address to point * to the start of the existing list */ /* set the existing list pointer to point to the new element */ ft\_lstadd\_front.c Copy #include "libft.h" void ft_lstadd_front(t_list **alst, t_list *new) { /* setting the new element's next address to point * to the start of the existing list */ new->next = *alst; /* set the existing list pointer to point to the new element */ *alst = new; } sun-brightdesktopmoon --- # CPP09 (to-do) | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp09-to-do#main-topics) Main topics Copy STL [PreviousCPP08 (to-do)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp08-to-do) [NextInception (doing)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # CPP08 (to-do) | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp08-to-do#main-topics) Main topics Copy Templated containers, iterators, algorithms [PreviousCPP07chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07) [NextCPP09 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp09-to-do) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide What I'll do here is create for you multiple checklists, that corresponds to different part of the project and that you can follow in order to build it. All the code for my "Minitalk" is available on my [Githubarrow-up-right](https://github.com/thebrisly/42-Cursus-Piscine/tree/master/minitalk) . If you have any question on it, don't hesitate to [contact](https://42-cursus.gitbook.io/guide/team) me (Laura) and it would be a pleasure for me to answer all the questions you might have. Let's go back to the chart I showed you at the [very beginning](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk) . ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F5eY61q1QT9MHUx2Zxf7g%252Fminitalk_scheme.png%3Falt%3Dmedia%26token%3D22a960bd-d30e-4e73-a4e7-a683b9c4d931&width=768&dpr=3&quality=100&sign=af87f37b&sv=2) minitalk explanatory scheme ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#overview) Overview We have a client that wants to send a message to the server. The message, "Hello" in our example, cannot be sent directly to the server. The client has to encrypt the message by sending a serie of signals (in my example I did it using bits, so 0's and 1's but if you find another method, feel free to do it) and the server has to decrypt/interpret it before it can be displayed. **Why can't you just send a message directly ?** As I said before, a signal is a kind of notification that is sent to a process. In this project we will be able to use only two type of signals: `SIGUSR1` and `SIGUSR2`. That means that when the client sends the signal `SIGUSR1` to the server process, it will take a certain action. And it will do something else when it receives the SIGUSR2 signal. chevron-rightShort example to understand why you can't just send a message directly[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#short-example-to-understand-why-you-cant-just-send-a-message-directly) Each time the client sends the "SIGUSR1" signal to a server, it must display "Hello World". Each time the client sends the "SIGUSR2" signal to a server, the server must display a random number. You can send "SIGUSR1" or "SIGUSR2" to the server as many times as you want, and the server will ALWAYS display the same thing - i.e. "Hello World" and/or a number (depending on the signal received). The code below will not work but it's for you to better understand what I'm saying. Here the SIGUSR1 signal is ONLY used to send the "Hello World" message to the server. If you want to send any other message, you won't be able to. Or you would need to change the output value again when the server receives SIGUSR1. Which is a bit annoying. It doesn't make much sense to go and change the server's output directly (and that would be cheating, because in the end you're not really sending a message, but just a signal that will send what you've pre-defined later). **The goal is that by using the SIGUSR1 and SIGUSR2 signals you can send a message - and it doesn't matter which one!** So you have to find a way to decrypt a message so that the server can display any message that is typed from the console. Here are two checklists to help you make your project a success: ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#client-checklist) Client Checklist In the "client.c" file, you will... * Write a program (main) in which the client takes two parameters/arguments * The PID of the server to which it wants to send the message * A message * Encrypt the message (I did the encryption via bits) * Send the message to the server (via its PID) * Create a stop condition so that the server knows when it has finished receiving the message ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#server-checklist) Server Checklist In the "server.c" file, you will... * Display its PID * Create an endless loop so that the server can receive signals at any time * Receive signals * Decrypt signals * For each signal received (SIGUSR1 & SIGUSR2) it should take a certain action ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#basic-checklist) Basic Checklist Of course you will also need to do these three things: * Makefile (create the "server" and "client" executables) * Manage errors & remove all leaks * Deal with the holy norminette And that's all. Once you really understand the concepts, you'll see that this project is very simple! So now, I'll let you try to find a solution and solve this problem... good luck! [PreviousFunctions usedchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used) [Nextpush\_swapchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap) Last updated 1 year ago * [Overview](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#overview) * [Client Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#client-checklist) * [Server Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#server-checklist) * [Basic Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing#basic-checklist) sun-brightdesktopmoon Copy /*client*/ int main() { kill(server_pid, SIGUSR1) //sends signal SIGUSR1 to a server kill(server_pid, SIGUSR2) //sends signal SIGUSR2 to a server } /* ---------------------------------------------------- */ /*server/ void signal_handler(int signum) { if (signum == SIGUSR1) //if the signal is equal to SIGUSR1 then he prints "Hello World" printf("Hello World); else if (signum == SIGUSR2) printf (" The random number is: %d", rand()); } int main() { sigaction(SIGUSR1, &signal_received, NULL); //every time it receives signal SIGUSR1 and will apply a specific function to it (signal handler) sigaction(SIGUSR2, &signal_received, NULL); //every time receives signal SIGUSR1 and will apply a specific function to it (signal handler) } sun-brightdesktopmoon --- # Install your virtual machine | Guide I'm not going to lie to you, I don't know how to install a virtual machine by myself. I had to follow some guides. Here is the one that i used: [https://github.com/pasqualerossi/Born2BeRoot-Guide/blob/main/README.mdgithub.comchevron-right](https://github.com/pasqualerossi/Born2BeRoot-Guide/blob/main/README.md) Other guides can be found on the internet. I used this one and it worked great! Feel free to use another one if it doesn't seem clear to you. From now, I will use this guide above and try to explain some theoretical things that are not explained there. circle-info I put my virtual machine & the image of debian on my sgoinfre directory. _sgoinfre_ is a server accessible from the 42 School network and available from each computer. It is a document server where you have a directory with your login name that only you can access. On each computer, there's also a folder called _goinfre,_ this folder let's you store some documents. This folder is different on each computer and larger than your session storage. If you put your virtual machine on the _sgoinfre_ server, you can change computer during your project, if you put it in the _goinfre_ folder, you have to stay on the same computer all along. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-1-2-downloading-and-installing-your-virtual-machine) Part 1, 2 - Downloading & installing your Virtual Machine ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ This part is quite simple to do. You are creating an empty virtual machine. It is as if you were setting up a computer from scratch. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-3-accessing-your-virtual-machine) Part 3 - Accessing your Virtual Machine ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- In this part you will configure the first elements of your machine. You will... * select the language, time zone & country on which your machine will run * create a hostname (your\_42\_login42) and a password for your machine * create a first simple user (your\_42\_login) and a password for it * configure the partitions of your machine ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#what-is-disk-partitioning-with-lvm) What is disk partitioning with LVM ? Disk _partitioning_ is the creation of one or more storage regions (called _partitions_), so that each region can be managed separately. Each OS has a different way to designate partitions. On Linux (and thus Debian or CentOS) they are designated like that: sdXN, with X a letter representing the medium and N the number of the partition on the medium (for example sdb3 for the third partition of disk b). Partitioning offers many advantages in terms of security. It is common practice to reserve partitions for services that can generate a lot of volume in order to avoid saturating the system partitions. Here is a short list of partitions that may exist (and that we use in this project): Name / Contains the rest of the tree. /boot Contains data that is used before the kernel begins executing user-mode programs /var Contains variable files /tmp Contains temporary files /home Contains HOME users And what's LVM ? You can think of LVM as "dynamic partitions", meaning that you can create/resize/delete LVM "partitions" (they're called "Logical Volumes" in LVM-speak) from the command line while your Linux system is running: no need to reboot the system to make the kernel aware of the newly-created or resized partitions. circle-info The next steps are the most important parts of the project - if you understand what you are doing here, you will be fine with the evaluation. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-4-5-6-configurating-your-virtual-machine) Part 4, 5, 6 - Configurating your Virtual Machine ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Now that you have installed your virtual machine, you have to fill it. Imagine that at this stage you just have an empty machine and you can't do anything. You have to add the tools you want to use. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#apt-vs-aptitude) `apt` vs `aptitude` You probably noticed that you used the command `apt` a lot during the configuration of your VM. Actually `aptitude` and `apt` are two of the popular tools which handle package management. In this project we used `apt` instead of `aptitude`. Even if they both offer the same basic functionality, installing and removing packages from the command-line, they have a little difference: * `aptitude` remembers which packages were explicitly requested and which were only installed due to dependencies. It will automatically uninstall packages which were not explicitly requested when they are no longer needed. * `apt` will only do explicitly what it is told to do in the command line ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#apparmor) APPArmor Linux security system that provides Mandatory Access Control (MAC) security. Allows the system admin to restrict the actions that processes can perform. It is included by default with Debian. Run `aa-status` to check if it is running. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#git-and-vim) Git & Vim If you are doing this project, you already used git and vim in the past. You will install these tools on your VM to be able to use them. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#ssh-secure-shell) SSH (Secure Shell) SSH stands for "Secure Shell", it is therefore a "shell" (or terminal) which is secure. A shell will allow you to administer your Linux servers, locally, that is to say when you are physically in front of your server, but also remotely! In particular thanks to Secure Shell (SSH). The use of the SSH protocol will allow you to connect remotely to your servers to manage them. For example, you can be in New York and manage your computer in Paris in a few clicks. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#ufw-uncomplicated-firewall) UFW (Uncomplicated Firewall) A firewall is an element of the computer network. Its role is to secure a network by defining the allowed or forbidden communications via rules. In other words it monitors incoming and outgoing network traffic and decides whether to block or allow traffic. In this project you will be asked to configure your operating system with the UFW firewall and leave only port 4242 open. You will need to set up a rule for this. ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#password-policy) Password Policy A password policy is a set of rules designed to improve security by encouraging users to use relatively strong passwords and to use them correctly. For example, in this project, it is asked to implement a strong password policy (which expires every 30 days, must be longer than 10 words and not contain a logical sequence, must contain capital letters, special characters and numbers). If your password can be guessed or easily hacked, it is likely to be vulnerable to hacking attempts and allows access to sensitive information. triangle-exclamation Each user of your virtual machine will have to follow the following password rules: * PASS\_MAX\_DAYS 30 * PASS\_MIN\_DAYS 2 * PASS\_WARN\_AGE 7 It is possible that your default user does not have these modifications, you will have to do it manually. To see which password parameter is associated with a user, you can type this command: `sudo chage -l username` if c does not correspond to the above figures, they must be changed manually as follows: `sudo chage -M 30 sudo chage -m 2 sudo chage -W 7 ` ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#groups-and-users) Groups and users Linux uses groups as a way to organize users. They exist to make permissioning of files and folders simpler. Linux was designed to allow more than one user to have access to the system at the same time but with different permissions. #### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#root) Root `root` is the super user and has the ability to do anything on a system. Therefore, in order to have an additional layer of security, a `sudo` user is generally used in place of root. #### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#sudo) Sudo You will need to install sudo. Sudo stands for "superuser do". In a few words `sudo` gives the designated user a super power. A power to act as an administrator temporarily. `sudo` is used to give another user limited access to another user’s account for the purpose of performing tasks. `sudo` enables a user to have administration privileges without logging in directly as root. This management of the rights given to users is contained in the file `/etc/sudoers` ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#crontab) Crontab Cron is a program that allows users of Unix systems to automatically execute scripts, commands or software at a pre-specified date and time, or on a pre-defined cycle. In this project you will have to post a message every 10 minutes. You will need cron in order to do it. Here is how it works: 1. You create a script (in our case it will be the monitoring script containing all the information) that you want to run using cron. 2. you type then `sudo crontab -u root -e` to open crontab and add a rule 3. The rule should be written like that: `* * * * * /` Where `* * * * *` means every minute of every hour of every day of every month and every day of the week. Let's take some examples: `0 * * * *` -this means the cron will run always when the minutes are `0` (so hourly) `0 1 * * *` - this means the cron will run always at 1 o'clock. `* 1 * * *` - this means the cron will run each minute when the hour is 1. So `1:00`, `1:01`, ...`1:59 */10 * * * *` \- means the cron will run each ten minutes. [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-7-signature.txt) Part 7 - Signature.txt ------------------------------------------------------------------------------------------------------------------------------------------------- A signature is a unique, identifying number for a hard disk drive or other data storage device. An operating system uses it to differentiate among storage devices on your computer. [PreviousWhat's a virtual machine ?chevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine) [NextP2P Evaluation - Questionschevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions) Last updated 1 year ago * [Part 1, 2 - Downloading & installing your Virtual Machine](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-1-2-downloading-and-installing-your-virtual-machine) * [Part 3 - Accessing your Virtual Machine](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-3-accessing-your-virtual-machine) * [What is disk partitioning with LVM ?](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#what-is-disk-partitioning-with-lvm) * [Part 4, 5, 6 - Configurating your Virtual Machine](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-4-5-6-configurating-your-virtual-machine) * [apt vs aptitude](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#apt-vs-aptitude) * [APPArmor](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#apparmor) * [Git & Vim](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#git-and-vim) * [SSH (Secure Shell)](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#ssh-secure-shell) * [UFW (Uncomplicated Firewall)](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#ufw-uncomplicated-firewall) * [Password Policy](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#password-policy) * [Groups and users](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#groups-and-users) * [Crontab](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#crontab) * [Part 7 - Signature.txt](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine#part-7-signature.txt) sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand FdF | Guide FdF is a graphic project in which you need to have new knowledge and master many new tools. In particular the minilibx of 42. But the subject can also be complex to understand... how to do it properly? Well, this is what we will see in this page ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#from-3d-to-2d) From 3D to 2D In the subject we are given an example of a map. This map corresponds to coordinates in a space (x,y,z). However, the screen of our computer is a surface with only two dimensions (x,y). We must therefore make a projection of the 3D points on a 2D plane. Here is an illustration to better visualize what I say: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fk2Jtnu3yS0SAPunmufmT%252Fimage.png%3Falt%3Dmedia%26token%3D2541f919-2a8f-4861-b0e8-67d3a3940e7c&width=768&dpr=3&quality=100&sign=e187fdd5&sv=2) Projection of a 3D cube on a 2D plane Above, you have an example of 4 different projections. For this project, they only ask you to do the "**isometric projection**". Let's take a more concrete example and start from scratch. \[insert scheme of fdf to better understand what we need to do - cube 3d (with 3 axes and cube 2d with 2 axes that represent a screen)\] ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#putting-the-dots-in-the-right-spots) Putting the dots in the right spots If we have a map of 8 points: (col = 0, 1, 2, 3 = x) 1 2 3 4 (line = 0 = y) 5 6 7 8 (line = 1 = y) With this, we can define 8 points. For example: * (x,y,z) = (0,0,1) | (x,y,z) = (1,0,2) | (x,y,z) = (1,1,6) | ... and so on However, your computer screen only has two coordinates (x and y). You can't see in 3D on your computer. You have to place the points in a certain way to create this 3D effect. Fortunately, this can be done with mathematical formulas. For one degree of projection we use: Since in the data it is asked to create an **isometric projection**, we will have to use another formula. The isometric projection is a perspective representation of an object, where the three main edges (which correspond to the three dimensions of the object) form equal angles of 120°. Here is the one I used: destination.x\=source.x∗cos(a)+source.y∗cos(a+2)+source.z∗cos(a−2)destination.x = source.x \* cos(a) + source.y \* cos(a + 2) + source.z \* cos(a - 2)destination.x\=source.x∗cos(a)+source.y∗cos(a+2)+source.z∗cos(a−2) destination.y\=source.x∗sin(a)+source.y∗sin(a+2)+source.z∗sin(a−2)destination.y = source.x \* sin(a) + source.y \* sin(a + 2) + source.z \* sin(a - 2)destination.y\=source.x∗sin(a)+source.y∗sin(a+2)+source.z∗sin(a−2) There are other formulas to reach the same result. I encourage you to do some tests so you can see the differences ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#connecting-the-dots) Connecting the dots Once you understand the above theory and have placed all the dots on your screen, you must now connect them. To do this, you will need to code an algorithm that allows you to connect two points together. There are several types of algorithms that have already been done and you can use them as inspiration. Here are some of them: * **DDA Line Algorithm**: [\[doc here\]arrow-up-right](https://www.thecrazyprogrammer.com/2017/01/dda-line-drawing-algorithm-c-c.html) * **Linear Interpolation:** [\[doc here\]arrow-up-right](https://en.wikipedia.org/wiki/Linear_interpolation) * **Bresenham:** [\[doc here\]arrow-up-right](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm) Personally I used the DDA because it is the simplest and less complicated to achieve the same result. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#to-summarize) To summarize * First you have to convert all your three-dimensional points (x,y,z) into two-dimensional points (x,y). * Once this is done, place the points on your screen (one point = one pixel). * Code an algorithm that connects the points together and draw all the pixels that connect them. This is not a complete checklist for the project. Afterwards, you have to pay attention to several other things that you will find in the final checklist. This one is just to help you understand the essential points of a projection. [PreviousFdFchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/fdf) [NextGraphics programmingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming) Last updated 2 years ago * [From 3D to 2D](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#from-3d-to-2d) * [Putting the dots in the right spots](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#putting-the-dots-in-the-right-spots) * [Connecting the dots](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#connecting-the-dots) * [To summarize](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/understand-fdf#to-summarize) sun-brightdesktopmoon Copy destination.x = source.x + cos(angle) * source.z destination.y = source.y + sin(angle) * source.z sun-brightdesktopmoon --- # ft_lstnew | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#subject) Subject Copy FT_LSTNEW (simplified) NAME ft_lstnew -- create a new list node element SYNOPSIS t_list *ft_lstnew(void *content); DESCRIPTION Allocate (with malloc(3)) and return the new element. The member variable 'content' is initialized with the value of the 'content' parameter. The 'next' variable is initialized to NULL. PARAMETERS content: The content of the new element RETURN VALUES The new element. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#understandable-explanation) Understandable explanation This function allocates memory for a new element of type `t_list`, setting its `content` to be the `content` parameter, and setting the `next` variable to `NULL`. Then it returns the newly allocated / created element of the list. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#commented-solution) Commented solution chevron-rightft\_lstnew[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#ft_lstnew) [PreviousBonus functionschevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions) [Nextft\_lstadd\_frontchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_front) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstnew#commented-solution) sun-brightdesktopmoon ft\_lstnew Copy /* declare a new list element */ /* allocate memory for it */ /* set the new element variables * new->content = content * new->next = NULL */ /* return the new element */ ft\_lstnew.c Copy #include "libft.h" t_list *ft_lstnew(void *content) { /* declaring the new list element */ t_list *elem; /* allocating the memory for the new element */ elem = malloc(sizeof(t_list)); if (!elem) return (NULL); /* setting the content of the new element * to the 'content' parameter * and setting the 'next' to NULL */ elem->content = content; elem->next = NULL; /* finally, we return the created element */ return (elem); } sun-brightdesktopmoon --- # Building the thing | Guide Firstly, I have to say that I won't be able to comment all my code and explain all of my code on here, there's too much files and things linked to one another that it would be impossible to do. What I'll do is create for you multiple checklists, that corresponds to different part of the project and that you can follow in order to build a complete game in C using [MiniLibX](https://42-cursus.gitbook.io/guide/minilibx) . All the code for my game is available on my [Githubarrow-up-right](https://github.com/Laendrun/42/tree/main/so_long) , if you have any question on it, don't hesitate to [contact](https://42-cursus.gitbook.io/guide/team) me (Simon) and it would be a pleasure for me to answer all the questions you might have. so\_long being a video game, that is something pretty personal, and you surely don't want to do exactly the same thing as I did (and I don't want you to neither), that's why, checklists is the best way to go. You'll have some ideas on where to start and what to do, and you still have to search for information and learn new things. Now that all that is said, let's get to work. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#map-checklist) Map checklist * Parse the map When parsing the map you can already check some errors, before even going further * Does the map file exist ? * Is the map rectangular ? All the lines should be the same length. * Is there something in the map file ? * Is the map enclosed in walls ? * Check the first and last lines and columns, they should all be `1` * Is there only one exit ? * Simply count how many `E` you find on the map. * Is there only one start position ? * Simply count how many `P` you find on the map. * Is there at least one collectibles ? * Simply count how many `C` you find on the map. All these checks can be made directly when you parse the map file. Now, if all these checks are ok, there's two more things you have to check on the map : is the exit accessible from the start position, and are all the collectibles accessible from the start position. Remember that you have to collect all collectibles to unlock the exit, so if not all collectibles are accessible, the map is invalid. The way that I checked that in my code is by using a sort of flood fill algorithm, starting on the start position. I check every tiles and what type they are, I update a counter each time the type of the tile is a collectible, same for the exit. At the end I can easily check if the collectibles counter is equal to the number of collectibles that I found when parsing the map, if they are different, not all collectibles are accessible, thus the map is invalid. I do the same thing for the exit, if the exit counter is 0, this means the exit is inaccessible, thus the map is invalid. An other way to check if the map is valid is to use a backtracking algorithm from the exit to the start position, and from all the collectibles to the start position. If any one of them couldn't reach the start position, the map is invalid. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#game-checklist) Game checklist * Create a window using MiniLibX * Create the required structure to store all the necessary information * Load all the required sprites (images) for your game and store them into memory * Create the different hooks * key\_handler * mouse\_handler (if necessary) * close\_handler, this is a hook on the red cross that closes the program correctly * loop\_hook (=> you game loop) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#render-checklist) Render checklist * Draw the background * Draw the not movable parts of the map * Draw the player ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#key-handler) Key handler The key handler (at least in my game), is mainly used to call the update\_player\_position function when W, A, S or D is pressed or to close the program correctly when we press the ESC key. There's some things you have to think about before updating the player position. * Is the requested new position a Wall ? * if the new position is a Wall, don't do anything. The subject says that the player should not be able to go through walls * Is the requested new position inside the map ? * if the new position is outside the map, don't do anything. Normally this shouldn't happen since the map is enclosed in walls but hey, never too sure. * Is the requested new position a Collectible ? * if yes, update the collected items counter and check * check if all collectibles have been collected * if yes, unlock the exit * update your map 2D array and replace the collectible by a "floor" tile so that it is not drawn in the next iteration of the game loop. * If the requested new position is not a wall, nor a collectible, nor outside the map, simply set the player position to the requested new position. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#final-word) Final word You have to assemble all these checklist to get the game working, and adapt it to your style of coding. As said earlier, if you want to see some code, take a look at my Github and ask me questions. That's basically all that you have to do to have a working game, but the big part is to find assets that fit the theme you want for your game. You can find a lot of free assets on [itch.ioarrow-up-right](https://itch.io/) (as said in the subject). You can also draw them yourself. You could use a program like [Asepritearrow-up-right](https://www.aseprite.org/) to draw some pixel art assets yourself, it's not free but it works great ! [PreviousCore conceptschevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/core-concepts) [Nextpipexchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex) Last updated 1 year ago * [Map checklist](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#map-checklist) * [Game checklist](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#game-checklist) * [Render checklist](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#render-checklist) * [Key handler](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#key-handler) * [Final word](https://42-cursus.gitbook.io/guide/2-rank-02/so_long/building-the-thing#final-word) sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand MiniRT | Guide This project was made by me ([Lauraarrow-up-right](https://github.com/thebrisly) ) and my fabulous mate ([fgrassetarrow-up-right](https://github.com/fgrasset) )! If you have any questions, don't hesitate to contact me on LinkedIn for example :-) I will be happy to help you ! We made a very, very minimalist RT without any bonuses because we wanted to go fast on it. But the bonuses shouldn't be too complicated to implement once you've got the hang of it ^^. Anyway, let's get on with understanding the subject! [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#what-is-raytracing) What is raytracing ? ----------------------------------------------------------------------------------------------------------------------------- Raytracing is a powerful technique in computer graphics used to generate realistic images by simulating how light interacts with objects in a scene. Instead of just putting shapes on a screen, **it acts like virtual light**. It pretends to shoot rays of light from a pretend camera, and these rays bounce around, lighting up everything they touch. By doing this, **it creates pictures that look super real because it copies how light really behaves**. Other drawing methods don't copy light as well, so **raytracing makes things look more like they do in the world around us**. Raytracing is incredibly effective at **producing high-quality and realistic images**, but it can also be quite **computationally intensive**. Because it simulates the behavior of light so accurately, it often requires a lot of calculations, which can slow down the rendering process. Video games used to use faster ways to draw, called rasterization. Nowadays, they're adding raytracing to games, mixing it with traditional methods. New hardware helps with this mix, improving how things look without sacrificing speed. This combo is called hybrid rendering, giving both realism and speed. Enough discussion. Let's see how the project works with diagrams. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#minirt-in-a-nutshell) MiniRT in a nutshell ------------------------------------------------------------------------------------------------------------------------------- ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#rendering-example) Rendering example Let's take a concrete example. Imagine your program receives this scene : `A 0.2 255,255,255 C 0,0,0 0,0,1 70 L 0,0,-3 0.6 sp 0,0,10 7 0,0,255` This scene should show only one sphere (sp) with a light source (L) coming from below and one camera (C) capturing the scene from the zero position. **The aim of the minirt project is to make a computer draw this scene in a realistic way.** This is how it would look from our program: \[picture of our project\] Sounds nice nooop ? But we went through a lot of shit to do this lol. **Here are the steps we followed in order to succeed !** ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#steps-to-get-there) Steps to get there To do this, the program first needs to figure out how to draw the sphere on the screen. In a drawing, **it would look something like this**: (sorry for my poor drawing skills, but you've got a little representation at least) ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FG0cpCld8P5JgV6DxMCkx%252Fimage.png%3Falt%3Dmedia%26token%3D5a0f6385-a9a5-4689-8fd7-8d2145607b5b&width=768&dpr=3&quality=100&sign=ea23a8e&sv=2) Imagine your computer screen divided into tiny squares, each representing a pixel. $ For every pixel, we imagine **launching a special ray of light from the camera's viewpoint**. This ray is like a question: "What's there?" As this ray travels, it might bump into objects in the scene, like the pink sphere you mentioned. If it hits the sphere, it's like the ray found an answer: "Ah, there's something here!" chevron-rightExplanation based on the drawing[hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#explanation-based-on-the-drawing) In my superb drawing, you can see that I'm shooting three rays from my camera towards my stage. All 3 rays will hit the object, but at 3 different points of light. The first point will be neither in shadow nor in direct light. The 2nd point will be in shadow and hardly visible from the camera's point of view (but still a little) and the last point, point 3, will be in direct contact with diffuse light - meaning it will be a point visible from the camera! Now, because we're not just interested in the object but also in how it's lit, we take another step. **We send a new ray from that point where the first ray hit the object, but this time towards the light** **source**. If this second ray reaches the light source, it's like saying, "Hey, can I see the light from here?" If it does, we know that light is reaching that point on the object. If it doesn't reach the light source, it's because it intersects another object (if there is more than one in the scene) before reaching the light or because it is in the shadow! **When light touches that point, we color it using the object's color**. So, in the case of the blue sphere, we'd color that point blue. And remember something. The closer a point is to the light and in direct contact with it, the brighter it will be! On the contrary, the further away it is, the shadier and darker (or even non-existent) it is. By repeating this process for every pixel and every object, we create an image that looks realistic, with objects casting shadows and reflecting light just like they would in the real world. It's like painting with rays of light to capture the essence of the scene. And... that's it (I promise, it really is !). But finding the right intersection, matrix and ray-tracing calculations takes time sometimes ! And you'll undoubtedly find other errors in your program along the way, which I'll list below. You also need to think about optimizing your code so that it doesn't take 8 hours to display a scene :) [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#common-error) Common error --------------------------------------------------------------------------------------------------------------- One very common mistake you're bound to encounter: Your objects appear pixelated. Like this: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FO6S8zgKsozkBnTj4qBTv%252Fimage.png%3Falt%3Dmedia%26token%3D4953e539-e48e-4943-88f9-fec08a21fc7c&width=768&dpr=3&quality=100&sign=4566fd91&sv=2) To solve this problem, I offer two suggestions : chevron-rightSolution 1 [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#solution-1) Just read the answer on this blog and you will understand everything : [https://stackoverflow.com/questions/23417736/ray-tracing-noisearrow-up-right](https://stackoverflow.com/questions/23417736/ray-tracing-noise) chevron-rightSolution 2[hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#solution-2) Once you've pinpointed where the ray hits the object and you're sending another ray towards the light source, it's important to check if any other objects in the scene get in the way. This means going through the list of all the objects. Remember to exclude the object you're currently dealing with – this prevents it from accidentally causing issues by calculating itself. This precaution can help you avoid potential problems in your calculations. That's it ! There is nothing more to know about this project. Or at least, I'll let you experiment with your code :D [PreviousMiniRTchevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/minirt) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing) Last updated 1 year ago * [What is raytracing ?](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#what-is-raytracing) * [MiniRT in a nutshell](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#minirt-in-a-nutshell) * [Rendering example](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#rendering-example) * [Steps to get there](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#steps-to-get-there) * [Common error](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt#common-error) sun-brightdesktopmoon sun-brightdesktopmoon --- # webserv (to-do) | Guide This project is here to make you write your own HTTP server. You will be able to test it with a real browser. HTTP is one of the most used protocol on internet. Knowing its arcane will be useful, even if you won't be working on a website. [PreviousProject Fileschevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/inception-doing/project-files) [Nextft\_transcendence (to-do)chevron-right](https://42-cursus.gitbook.io/guide/6-rank-06/ft_transcendence-to-do) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # CPP (00 - 04) (doing) | Guide Before diving into the core of these five first C++ modules let's first understand the basics of what is C++ and more specifically what is _Object Oriented Programming_ (OOP). Also, I encourage you to look at the videos on the Intra before going further, each subject has its own video explaining it. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#what-is-object-oriented-programming) What is object oriented programming ? To start, I'll let you read [thisarrow-up-right](https://www.techtarget.com/searchapparchitecture/definition/object-oriented-programming-OOP) article from _TechTarget_. This article is a good starting point, but it's only a starting point, it contains a lot of words and topics that you can search to get a better understanding of everything. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#what-is-c) What is C++ ? First of all, watch [thisarrow-up-right](https://www.youtube.com/watch?v=MNeX4EGtR5Y) short video introduction of C++. [Herearrow-up-right](https://www.w3schools.com/cpp/default.asp) is a complete introduction C++ guide / tutorial on **w3schools.** I encourage you to read through it, you don't need to remember all the details but at least read through it so you can store in your head the basic principles and ideas of C++ to go search for them in more details again when you need / encounter them when doing the different exercises. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#c-modules) C++ Modules C++ is composed of 10 modules, splitted on two circles, the five firsts modules are on this rank (00-04), and the five lasts are on the next rank (05-09). All the C++ modules work the same way as the C modules did during your pisicine, each module is splitted into multiple exercises. Some of the modules can be validated by doing 80% of the module, and other require 100%, like in the piscine. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#c-on-this-gitbook) C++ on this GitBook For most of the modules, I won't go into the details of each and every exercises in these modules. I'll go over the main topics that are present on the first page of the subjects. Some of the modules, the more complex ones, will be a little more described with some examples and all, but that would do a lot to write if I described every exercises in details. [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing) [NextCPP00chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00) Last updated 2 years ago * [What is object oriented programming ?](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#what-is-object-oriented-programming) * [What is C++ ?](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#what-is-c) * [C++ Modules](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#c-modules) * [C++ on this GitBook](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing#c-on-this-gitbook) sun-brightdesktopmoon sun-brightdesktopmoon --- # CPP04 (doing) | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp04-doing#main-topics) Main topics Copy Subtype polymorphism, abstract classes, interfaces [PreviousCPP03chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03) [NextNetPracticechevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Building the thing | Guide What I'll do here is create for you multiple checklists, that corresponds to different part of the project and that you can follow in order to build it. All the code for my "FdF" is available on my [Githubarrow-up-right](https://github.com/thebrisly/42-Cursus-Piscine/tree/master/FdF) . If you have any question on it, don't hesitate to [contact](https://42-cursus.gitbook.io/guide/team) me (Laura) and it would be a pleasure for me to answer all the questions you might have. To realize FdF I created 6 `.c` files: * `fdf.c`: the place where the `main` is located, error handling and memory allocation * `start.c`: the place where I initialize my graphic variables and where I do preliminary checks * `points.c`: the place where I create my three and two dimensional point tables * `limits.c`: the place where I define which point should connect to another point * `draw.c`: this is where I have all my formulas and functions that allow me to draw what I want * `hooks.c`: the place where I give instructions to interact with the mouse and keyboard and of course a `.h` called "`fdf.h`" where I have the most important and biggest structure. We'll go through all these files via checklists so you can see what logic I applied. triangle-exclamation There must be NO leaks. Check that you free the allocated memory each time ! Of course you can do otherwise than what I have shown you above. Here is a more global checklist to make the project your own and make it the best you can. I didn't put everything otherwise it will not be understandable ^^ I hope it will be useful... ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#some-checklists) (some) Checklists #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#main-checklist) Main Checklist * Check that there are only 2 arguments * Free the allocated memory (no leaks) #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#map-checklist) Map Checklist * Get and store the map data somewhere (coordinates, height, length...) * Error handling of the map * Empty map (should not segfault if given to you) * Map not rectangular (should not segfault if given to you) #### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#graphical-programmation-checklist) Graphical Programmation Checklist * Initialize the display, the window and the image * Initialize the infinite loop for your graphic environment ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#fdf.c) fdf.c I created three functions in this file. One that handles errors (simply exit the program and display a message when called), one that frees the tables that I don't need any more and a main that can be defined by these tasks: ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#points.c) points.c This file is very simple. It simply initializes my array with three-dimensional points (x,y,z) and another array with two-dimensional points (x,y) that I create from the three-dimensional points. * From the the data stored in start.c (the map data), i created a single list with all 3D points * From the list containing all 3D points I created another single list with all 2D points * Check that you use the correct formula to convert your points ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#hooks-checklist) hooks Checklist * The window and the program should close properly when... * You click on ESC * You close the window by clicking on the cross * **FdF BONUS** * When you use the mouse cursor downwards you zoom the image * When you use the mouse cursor upwards you zoom out the image * When you press w,a,s,d (or the arrows) you can move * When you click on another key you can rotate (change the angle of the image) * Add another bonus you like I hope this helps! Let me know if you have any other questions. [PreviousGraphics programmingchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/graphics-programming) [NextPhilosopherschevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers) Last updated 2 years ago * [(some) Checklists](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#some-checklists) * [fdf.c](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#fdf.c) * [points.c](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#points.c) * [hooks Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/fdf/building-the-thing#hooks-checklist) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_lstdelone | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#subject) Subject Copy FT_LSTDELONE (simplified) NAME ft_lstdelone -- removes one element from the list SYNOPSIS void ft_lstdelone(t_list *lst, void (*del)(void *)); DESCRIPTION Free the memory of the element passed as parameter using the 'del' function then free(3). The memory of 'next' must not be freed. PARAMETERS lst: the element to free del: address of the function that can delete the element's content RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS free(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#understandable-explanation) Understandable explanation This function takes a list element as parameter and deletes its content as well as free the allocated memory using the `del` function passed as parameter too. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#commented-solution) Commented solution chevron-rightft\_lstdelone[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#ft_lstdelone) [Previousft\_lstadd\_backchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back) [Nextft\_lstclearchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone#commented-solution) sun-brightdesktopmoon Copy /* use the delete function on the element's content */ /* free the element */ ft\_lstdelone.c Copy #include "libft.h" void ft_lstdelone(t_list *lst, void (*del)(void *)) { /* use the del function on the element's content */ del(lst->content); /* free the element */ free(lst); } sun-brightdesktopmoon --- # ft_lstlast | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#subject) Subject Copy FT_LSTLAST (simplified) NAME ft_lstlast -- get the last element of the list SYNOPSIS t_list *ft_lstlast(t_list *lst); DESCRIPTION Returns the last element of the list PARAMETERS lst: the start of the list RETURN VALUES Last element of the list AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#understandable-explanation) Understandable explanation I think that for this one the subject is clear enough, we have to return a pointer to the last element of the list, it's pretty easy to understand. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#hints) Hints For this one, we basically have to do the same thing as for the `ft_lstsize` function but we don't need to count how many elements are in the list nor return the count, but we directly return the `tmp` element. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#commented-solution) Commented solution chevron-rightft\_lstlast[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#ft_lstlast) [Previousft\_lstsizechevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstsize) [Nextft\_lstadd\_backchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast#commented-solution) sun-brightdesktopmoon ft\_lstlast.c Copy #include "libft.h" t_list *ft_lstlast(t_list *lst) { t_list *tmp; if (!lst) return (NULL); tmp = lst; /* instead of looping directly over the element, we check if * there is a next element in the list, if not, that means we * reached the end and we have to return the current pointer * if we looped over the element directly like for ft_lstsize * we would be returning NULL every time */ while (tmp->next) tmp = tmp->next; return (tmp); } sun-brightdesktopmoon --- # ft_lstclear | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#subject) Subject Copy FT_LSTCLEAR (simplified) NAME ft_lstclear -- removes the element passed as parameter and all the following elements SYNOPSIS void ft_lstclear(t_list **lst, void (*del)(void *)); DESCRIPTION Deletes and free the memory of the element passed as parameter and all the following elements using 'del' and free(3). Finally, the initial pointer must be set to NULL. PARAMETERS lst: pointer address to one element del: address of the function that can delete the element's content RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS free(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#understandable-explanation) Understandable explanation This functions works similarly as the `ft_lstdelone` function, but instead of removing only one element, it removes the element passed as parameter as well as all the following elements. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#commented-solution) Commented solution chevron-rightft\_lstclear[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#ft_lstclear) [Previousft\_lstdelonechevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone) [Nextft\_lstiterchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#understandable-explanation) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear#commented-solution) sun-brightdesktopmoon ft\_lstclear.c Copy #include "libft.h" void ft_lstclear(t_list *lst, void (*del)(void *)) { t_list *tmp; /* loop over the list */ while (*lst) { /* set the tmp to point to the next element of the list */ tmp = (*lst)->next; /* use ft_lstdelone on the current element */ ft_lstdelone(*lst, del); /* set the list pointer equal to tmp, so that we have a * pointer to the next element */ *lst = tmp; } /* free the list pointer and set it to NULL */ free(*lst); *lst = NULL; } sun-brightdesktopmoon --- # CPP (05-09) (to-do) | Guide [CPP05chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp05) [CPP06 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp06-to-do) [CPP07chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07) [CPP08 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp08-to-do) [CPP09 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp09-to-do) [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing) [NextCPP05chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp05) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Understand pipex | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#goal) Goal chevron-rightProject-specific guidelines[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#project-specific-guidelines) * Your program will be executed like this `./pipex file1 cmd1 cmd2 file2` * `file1` and `file2` are filenames * `cmd1` and `cmd2` are shell commands with their arguments * Your program has to do the exact same thing as the following shell command * `$> < file1 cmd1 | cmd2 > file2` * Your program must not leak any memory ! The goal of pipex is to develop a program that simulates the pipes in the shell. This program will use a lot of new functions that we have never seen before, so I'll try to go over them all in the next section. If you look at the example given in the subject, your program has to reproduce exactly the following shell command. Copy < file1 cmd1 | cmd2 > file2 Before going further, we have to understand clearly what this command does. Let's take a command example and go through it left to right. Copy < infile grep a1 | wc -w > outfile ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#less-than-symbol) < symbol The `<` symbol is an "input redirection" symbol. In that case, the `<` symbol redirects the content of `infile` to the `standard input` so that when `grep` is reading from the `standard input`, it gets the content of `infile`. Let's use a more easy to understand syntax that works the same way. Copy grep a1 < infile | wc -w > outfile This way, we can better see that the content of the `infile` is used by the `grep` command. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FuYUzNvq5HaKuDT0lO0Og%252FScreenshot%25202023-01-02%2520at%252010.13.18.png%3Falt%3Dmedia%26token%3De688761f-cc85-46d5-9ae5-530582d26370&width=768&dpr=3&quality=100&sign=d7bacf2c&sv=2) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#or-symbol) | symbol The `|` (pipe) symbol redirects the `output` of the command on the left to the `input` of the command on the right. In that case, the `|` symbol redirects the `output` of the `grep` command to the `input` of the `wc` command. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FgcDY7ENPkgWarC8vZgb4%252FScreenshot%25202023-01-02%2520at%252010.07.28.png%3Falt%3Dmedia%26token%3D5bc71306-c21a-44ff-aa5e-288cd7c06f8e&width=768&dpr=3&quality=100&sign=d219c96c&sv=2) Without `|` symbol Without the pipe symbol, the output of the grep command is written directly to the standard output, let's add the pipe symbol in now. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fv4Wxg4ZvE3SSxLobYKbt%252FScreenshot%25202023-01-02%2520at%252010.08.50.png%3Falt%3Dmedia%26token%3Dabd9f43f-f0b1-4e4f-89ad-a93c4e154bea&width=768&dpr=3&quality=100&sign=3d0ecb5a&sv=2) Redirecting `grep` result to `wc` using the pipe symbol As you can see, the output is now the result of the `wc` command, but the result of the `wc` command on the result of the `grep` command. That's why you see 20, if you count the number of words we had before when running only grep, that is 20. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#greater-than-symbol) \> symbol The `>` symbol is an "output redirection" symbol. In that case, the `>` symbol writes the `output` of the `wc` command into the `outfile`. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FKCEe0GyF8wUizEiJk4IZ%252FScreenshot%25202023-01-02%2520at%252008.31.48.png%3Falt%3Dmedia%26token%3D82bf8fff-758c-44cd-9322-b2e5c65a0d20&width=768&dpr=3&quality=100&sign=8a9de0ed&sv=2) That's the result of the command without the `>` symbol ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F0ZyJ56GV8Av1YkZ88bz3%252FScreenshot%25202023-01-02%2520at%252008.33.07.png%3Falt%3Dmedia%26token%3Df26a771e-985e-4ade-88fe-97c9b8a0f841&width=768&dpr=3&quality=100&sign=37a3c4bd&sv=2) The same command with the `>` symbol, there's nothing to see on the standard output. Actually, both commands give the same result, the `infile` didn't change between both, but the second time, the output was written in the `outfile` file, let's take a look at it. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FFZueILhUgl0uzBWv2FU9%252FScreenshot%25202023-01-02%2520at%252008.35.01.png%3Falt%3Dmedia%26token%3D5b90b4d0-d510-4c58-8e52-2b45719854a4&width=768&dpr=3&quality=100&sign=38d08deb&sv=2) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#greater-than-greater-than-symbol) \>> symbol The `>>` symbol does almost the same thing as the `>` symbol. The `>` symbol replaces the content of the file on the right with the output of the command on the left. The `>>` symbol appends the output of the command on the left at the end of the file. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FklqIJgdMlhtsIRh9eeg3%252FScreenshot%25202023-01-02%2520at%252008.25.32.png%3Falt%3Dmedia%26token%3De0653a27-ed3b-48ea-9f67-6ce7d3b8316c&width=768&dpr=3&quality=100&sign=36614f57&sv=2) `>>` example Let's take a look at what the `outfile` looks like after these two commands. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FnS5f5eTO15LeE4K8OgWG%252FScreenshot%25202023-01-02%2520at%252008.28.30.png%3Falt%3Dmedia%26token%3Db36350c9-df8c-41b4-83ce-e9f945e3c534&width=768&dpr=3&quality=100&sign=7f4ce07d&sv=2) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#less-than-less-than-symbol) << symbol There's also this thing for the bonus `<<`. The `<<` symbol is an input "redirection" symbol. It makes the shell read from the standard input until it encounters **only** a specific `LIMITER` on the stdin. Let's ake a look at the example from the subject. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FklqIJgdMlhtsIRh9eeg3%252FScreenshot%25202023-01-02%2520at%252008.25.32.png%3Falt%3Dmedia%26token%3De0653a27-ed3b-48ea-9f67-6ce7d3b8316c&width=768&dpr=3&quality=100&sign=36614f57&sv=2) `<<` example As you can see, the first `cat` command waited until I wrote `LIM` and **only** `LIM` on the stdin before going further. Your `pipex` should do the same. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F7n9AalgbtO0QZtENRhtO%252FScreenshot%25202023-01-02%2520at%252008.20.15.png%3Falt%3Dmedia%26token%3D34dda83e-9364-4a1c-8d3a-364657a50961&width=768&dpr=3&quality=100&sign=afa3801a&sv=2) [Previouspipexchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/pipex) [NextFunctions usedchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used) Last updated 1 year ago * [Goal](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#goal) * [< symbol](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#less-than-symbol) * [| symbol](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#or-symbol) * [\> symbol](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#greater-than-symbol) * [\>> symbol](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#greater-than-greater-than-symbol) * [<< symbol](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex#less-than-less-than-symbol) sun-brightdesktopmoon Copy cmd << LIMITER | cmd1 >> file sun-brightdesktopmoon --- # Building the thing | Guide Push\_swap is not a very difficult project in terms of code construction. You will see that it doesn't need many steps to finish it. The hardest part is to find a solution to the problem and to to construct its algorithm. As usual, in this page I will make checklists for you to succeed push swap at best ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#main-checklist) Main Checklist * Decide if you are going to do your project using chained lists or using tables * Handle the arguments you are given in input * (If you choose radix sort, normalize your data ! ) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#error-checklist) Error Checklist There are a lot of errors to handle in push\_swap. Don't forget any of them! * **The program must work with several numerical arguments** * ./push\_swap 1 3 5 +9 20 -4 50 60 04 08 * **The program also works if you receive a single character list as a parameter** * ./push\_swap "3 4 6 8 9 74 -56 +495" * **The program should NOT work if it encounters another character** * ./push\_swap 1 3 dog 35 80 -3 * ./push\_swap a * ./push\_swap 1 2 3 5 67b778 947 * .push\_swap " 12 4 6 8 54fhd 4354" * ./push\_swap 1 -- 45 32 * these examples should return "Error\\n" * **The program should NOT work if it encounters a double number** * ./push\_swap 1 3 58 9 3 * ./push\_swap 3 03 * ./push\_swap " 49 128 50 38 49" * these examples should return "Error\\n" * ./push\_swap "95 99 -9 10 9" * this example should work because -9 & 9 are not equal * **The program should work with INT MAX & INT MIN** * ./push\_swap 2147483647 2 4 7 * ./push\_swap 99 -2147483648 23 545 * ./push\_swap "2147483647 843 56544 24394" * these examples should work and sort your list * ./push\_swap 54867543867438 3 * ./push\_swap -2147483647765 4 5 * ./push\_swap "214748364748385 28 47 29" * these examples should return "Error\\n" * **Nothing has been specified when strings and int are mixed.** It's up to you what you want to do * ./push\_swap "1 2 4 3" 76 90 "348 05 ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#instructions-checklist) Instructions Checklist This checklist will help you to verify that you have coded all the instructions (11) to use them in your algorithms (next step). If you don't understand what these functions do you can check the [main page of push\_swap](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap) where you will be given a better explanation * **sa (swap a)**: If there are 2 numbers, swap the first 2 elements at the top of the stack a. * **sb (swap b )** : If there are 2 numbers, swap the first 2 elements at the top of the stack b. * **ss** : sa and sb at the same time. * **pa (push a)**: If b is not empty it takes the first element on top of b and puts it on a. * **pb (push b)**: If a is not empty, it takes the first element on top of a and puts it on b. * **ra (rotate a)**: Shifts all the elements of the stack a up by one position. The first element becomes the last. * **rb (rotate b)** : Shifts all the elements of the stack b one position upwards. The first element becomes the last one. * **rr** : ra and rb at the same time. * **rra (reverse rotate a)**: Shifts all elements of the stack down one position. the stack a. The last element becomes the first. * **rrb (reverse rotate b)**: Shifts all the elements of the stack b one position downwards. the stack b. The last element becomes the first. * **rrr** : rra and rrb at the same time ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#algorithm-sort-checklist) Algorithm/Sort Checklist * Check if the order of the list is correct or if it should be sorted * Make a small algorithm for small numbers (5 and less) * Implement a condition for 2 numbers * Create an algorithm for 3 numbers * Create an algorithm for 4 numbers * Create an algorithm for 5 numbers * Create another algorithm for all other numbers And obviously at the end check if everything is correct ! **No leaks should be present**, remember to always free the allocated memory when you are not using it anymore. And that's it... Good luck with the code! If you have any other questions don't hesitate to contact me (Laura), and I'll be happy to help you :) [PreviousAlgorithmschevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/algorithms) [NextFdFchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/fdf) Last updated 1 year ago * [Main Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#main-checklist) * [Error Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#error-checklist) * [Instructions Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#instructions-checklist) * [Algorithm/Sort Checklist](https://42-cursus.gitbook.io/guide/2-rank-02/push_swap/building-the-thing#algorithm-sort-checklist) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_putstr_fd | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#subject) Subject Copy FT_PUTSTR_FD (simplified) NAME ft_putstr_fd -- write a string on a specified file descriptor SYNOPSIS void ft_putstr_fd(char *s, int fd); DESCRIPTION Write the string s on the file descriptor fd. PARAMETERS s: string to write fd: file descriptor on which to write RETURN VALUES ft_putstr_fd() does not return anything AUTHORIZED EXTERNAL FUNCTIONS write(2) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#understandable-explanation) Understandable explanation This one is pretty straight forward, you already know how to write the `ft_putstr()` function, if you don't remember, look back at what you did during your Piscine. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#hints) Hints Take a look at the man for the `write(2)` function, the first parameter is... you guessed it ! A file descriptor, so I mean, do you really need to have the code for this ? I hope you can figure it out. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#commented-solution) Commented solution chevron-rightft\_putstr\_fd[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#ft_putstr_fd) [Previousft\_putchar\_fdchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putchar_fd) [Nextft\_putendl\_fdchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putstr_fd#commented-solution) sun-brightdesktopmoon ft\_putstr\_fd.c Copy #include "libft.h" void ft_putstr_fd(char *str, int fd) { int i; i = 0; while (str[i]) { write(fd, &str[i], 1); i++; } } sun-brightdesktopmoon --- # Minishell | Guide Well... As it is the most complexe project of 42 school (beside transcendence), where you will learn a lot of new concepts and new functions, we will give you short explanation about some little things only. Minishell is really personal and is really complexe to explain... So let's get right into it. [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing) [NextUnderstand Minishellchevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/understand-minishell) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_lstmap | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#subject) Subject Copy FT_LSTMAP (simplified) NAME ft_lstmap -- creates a new list resulting from the application of f to each element SYNOPSIS t_list *ft_lstmap(t_list *lst, void (*f)(void *), void (*del)(void *)); DESCRIPTION Iterate over the list 'lst' and apply the function 'f' to the content of each elements. Create a new list resulting of the successive applications of 'f'. The function 'del' is used to destroy the content of an element if necessary. PARAMETERS lst: pointer address to one element f: the address of the function to apply del: the address of the function that can delete an element's content RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#understandable-explanation) Understandable explanation This functions works similarly as the `ft_lstiter` function, but it creates a new list resulting of the successive applications of `f` on each element's content. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#commented-solution) Commented solution chevron-rightft\_lstmap[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#ft_lstmap) [Previousft\_lstiterchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter) [NextBorn2beRootchevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap#commented-solution) sun-brightdesktopmoon Copy /* check if lst or f or del is NULL */ /* loop over lst */ /* create a new element */ /* if new elem is null, clear the new list */ /* add the new element to the back of the list */ /* finally, return the new list */ Copy #include "libft.h" t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) { t_list *new_list; t_list *new_obj; if (!lst || !f || !del) return (NULL); new_list = NULL; /* loop over the existing list */ while (lst) { /* create a new object with the content being the result * of the application of the function f on the current element's * content */ new_obj = ft_lstnew(f(lst->content)); if (!new_obj) { /* if the new object is null, clear the new list */ ft_lstclear(&new_list, del); return (NULL); } /* if there is a new object, add it to the back of the new list */ ft_lstadd_back(&new_list, new_obj); lst = lst->next; } /* finally, we return the new list */ return (new_list); } sun-brightdesktopmoon --- # ft_lstadd_back | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#subject) Subject Copy FT_LSTADD_BACK (simplified) NAME ft_lstadd_back -- adds a new node at the end of the list SYNOPSIS void ft_lstadd_back(t_list **lst, t_list *new); DESCRIPTION Add the 'new' element at the end of the list PARAMETERS lst: pointer address of the first element of the list new: pointer address of the new element to add to the list RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#understandable-explanation) Understandable explanation This function lets us add a new element to the end of an existing list. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#commented-solution) Commented solution chevron-rightft\_lstadd\_back[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#ft_lstadd_back) [Previousft\_lstlastchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstlast) [Nextft\_lstdelonechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstdelone) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstadd_back#commented-solution) sun-brightdesktopmoon Copy /* get the last element of the list */ /* set the last->next variable to point to the new element */ /* if last is NULL, make the list pointer point to the new element */ ft\_lstadd\_back.c Copy #include "libft.h" void ft_lstadd_back(t_list **alst, t_list *new) { t_list *last; /* using ft_lstlast to get the last element of the list */ last = ft_lstlast(*alst); /* if last is NULL, there is no list, so we set the list pointer * to point to the new element */ if (!last) *alst = new; /* we set the last's next variable to point to the new element */ last->next = new; } sun-brightdesktopmoon --- # ft_lstiter | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#subject) Subject Copy FT_LSTITER (simplified) NAME ft_lstiter -- apply a function to each element's content SYNOPSIS void ft_lstiter(t_list *lst, void (*f)(void *)); DESCRIPTION Iterate over the list 'lst' and apply the function 'f' to the content of all elements. PARAMETERS lst: pointer address to one element f: function to apply RETURN VALUES None AUTHORIZED EXTERNAL FUNCTIONS None ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#understandable-explanation) Understandable explanation This function iterates over the whole list and applies the function `f` to the content of each elements. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#commented-solution) Commented solution chevron-rightft\_lstiter[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#ft_lstiter) [Previousft\_lstclearchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstclear) [Nextft\_lstmapchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstmap) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions/ft_lstiter#commented-solution) sun-brightdesktopmoon Copy /* loop over the entire list */ /* apply the function 'f' to the content of each elements */ ft\_lstiter.c Copy #include "libft.h" void ft_lstiter(t_list *lst, void (*f)(void *) { t_list *tmp; tmp = lst; /* loop while tmp is not null */ while (tmp) { /* apply the function f to the content of the current * element */ f(tmp->content); /* set tmp to point to the next element */ tmp = tmp->next; } } sun-brightdesktopmoon --- # ft_bzero | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#subject) Subject Copy BZERO(3) (simplified) NAME bzero -- write zeroes to a bye string SYNOPSIS void bzero(void *s, size_t n); DESCRIPTION The bzero() function writes n zeroed bytes to the string s. If n is zero, bzero() does nothing. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#understandable-explanation) Understandable explanation This function works the same way as the `memset()` function, except you don't have to specify what character to write, it'll always be `0` (`NUL` character). This function does not return anything and if the number of characters to write you passed as `size_t n` is `0`, `bzero` does nothing. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#hints) Hints ft\_bzero.c Copy void ft_bzero(void *s, size_t n) { /* declare a temporary pointer */ /* make the temporary pointer equal to *s converted to a char * */ /* loop on the temporary pointer while we didn't reach n characters */ /* in that loop, set the current byte equal to 0 */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#commented-solution) Commented solution chevron-rightft\_bzero[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#ft_bzero) [Previousft\_memsetchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset) [Nextft\_memcpychevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero#commented-solution) sun-brightdesktopmoon ft\_bzero.c Copy #include "libft.h" void ft_bzero(void *s, size_t n) { /* declaring our temporary pointer */ char *tmp_ptr; /* making our temporary pointer equal to b converted to char * */ tmp_ptr = (char *) s; /* looping on our temporary pointer while we didn't reach n */ while (n > 0) { /* assigning 0 to the current byte in our temporary pointer */ *(tmp_ptr++) = 0; /* reducing the n by one so we only set n bytes to 0 */ n--; } } sun-brightdesktopmoon --- # Building the thing | Guide This project was divided into 4 parts 1. The first part concerns **parsing and reading input files** 2. The second part is a little more mathematical and concerns **intersections and ray tracing** 3. Then the **management of light, shadows and colors** 4. And finally all the **graphic management** (windows, hooks, etc.). **with the minilibx** Let's look at each of the 4 parts in detail [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#parsing) Parsing ------------------------------------------------------------------------------------------------------ Parsing isn't very complicated, but it does take a long time... a very long time! Here is the list of almost everything that you need to check: * File management (non-existent, empty files, etc.) * The types correspond to the requested types and nothing else * There is a MAXIMUM of one camera, one diffused light and one ambient light (there can be 0 or one, but no more!) * Each line corresponding to a type must have the right number of elements * If it's a color, it has to be in the right range (0 - 255) and the same goes for orientation vectors (-1,1), etc. Make sure all digits are in the correct range for each type. * For each object, you also need to pay attention to its specific characteristics (whether the diameter or height of a cylinder is non-negative, for example, or other things). Visually it would look like this: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FZQDVYouvuJQlN1AEO8MX%252Fimage.png%3Falt%3Dmedia%26token%3D9b6e45d2-6ac5-4be7-a494-2de8988eaf30&width=768&dpr=3&quality=100&sign=8d59355e&sv=2) There are a LOT of parameters to take into account. Just try to make sure it doesn't segfault when you take a scene in the parameter of your program ! :) [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#intersections-and-raytracing) Intersections and raytracing ------------------------------------------------------------------------------------------------------------------------------------------------ Here, the focus shifts to a core challenge: finding intersections. The goal is to determine where the rays cast from the camera hit different objects in the scene. This process involves intricate steps to calculate intersections with various shapes like spheres, planes, and cylinders. * For spheres, it requires solving quadratic equations to find the points where the ray and the sphere's surface meet. * Planes involve straightforward geometric calculations to determine where the ray intersects the plane. * Cylinders require a bit more complexity, involving calculations to find where the ray crosses the cylindrical surface. Successfully mastering these calculations is essential as it forms the foundation for accurately tracing rays and creating the visual representation of the scene. To sum up, here's a little to-do list of what you can do: * Send rays from the camera position to each pixel of the screen. * Determine where each ray intersects with the objects in the scene (spheres, planes, cylinders). * Calculate the precise points of intersection by solving equations or using geometric methods. * Intersection with a sphere * Intersection with a plane * Intersection with a cylinder * Evaluate the distance between the camera and the intersection points to understand what's closest. * Decide which object the ray hits first by comparing distances to the intersection points * Once the closest object is identified we can try to find out what color the pixel will be and how bright it will be (next step) [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#lights-and-shadows) Lights and shadows ---------------------------------------------------------------------------------------------------------------------------- In this step, we make things look real with light and shadows. We check if objects are lit or in shadow by sending rays to light sources. We use angles to decide how bright things should be. Background light and distance effects are also added. * Once the closest object is identified, cast new rays from the intersection point towards light sources. * If one of these rays intersects with another object before it reaches the light source, it's like catching the object casting a shadow on itself. This shadow indicates that the point is not directly illuminated by the light. * Conversely, if the ray reaches the light source without obstruction, the point basks in direct illumination – it's in the light. * When a point is in the light, assess the angle at which the light strikes the object's surface. This angle helps determine how intense the light's effect should be on the point (or any other method if you find a better one) * Introduce the concept of ambient light, which mimics the soft, indirect illumination from all directions in the environment. This is like a gentle, uniform glow that helps prevent overly dark shadows. * Contemplate how light attenuates, growing weaker as it travels. Objects farther from the light source receive less light intensity, which influences their brightness. * Blend all these factors together, calculating how they contribute to the final color of the pixel at that point on the screen. This color is a result of intricate interactions between light and the object's characteristics. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#graphic-management) Graphic Management ---------------------------------------------------------------------------------------------------------------------------- This part involves creating a graphical interface using the minilibx library to display the rendered image. The library provides tools to open windows, handle keyboard inputs, and interact with the user. Here's a breakdown of the steps: * Initialize minilibx * Create a window * Handler user inputs / hooks (close the program/window with the cross or by pressing ESC) * Render the image (call your raytracing function) * Display the image (put your pixels one by one) And that's it ! Don't forget other basic things such as error handling and leaks management ;) I really hop that you'll have as much fun as we've had on this project! And we wish you good luck and a lovely adventure. don't forget that if you have any questions, you can come and [ask mearrow-up-right](https://www.linkedin.com/in/laura-fabbiano/) . [PreviousUnderstand MiniRTchevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/understand-minirt) [NextCPP (05-09) (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do) Last updated 1 year ago * [Parsing](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#parsing) * [Intersections and raytracing](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#intersections-and-raytracing) * [Lights and shadows](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#lights-and-shadows) * [Graphic Management](https://42-cursus.gitbook.io/guide/4-rank-04/minirt/building-the-thing#graphic-management) sun-brightdesktopmoon sun-brightdesktopmoon --- # NetPractice | Guide Okay - let's put the code aside for a second and get down to something mystical: networks. * How do two machines communicate with each other? * What is the Internet anyway? * Do you even know what an IP address is? All these network-related questions can be answered to perfection thanks to NetPractice, a project from 42. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice#netpractice-in-short) NetPractice in short What you'll have to do: * Download a file from your intra site Once that's done, you're going to have some fun with a few problem-solving games: * You'll need to configure small networks. To do this, you'll need to understand how addressing works with the TCP/IP protocol. (You'll have 10 levels) Here's an example: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FNy29WVZDUVPTknz7zQHl%252Fimage.png%3Falt%3Dmedia%26token%3Dac9302ad-70a4-4683-b0bb-e6cee8f2dba9&width=768&dpr=3&quality=100&sign=f8d931cf&sv=2) Example of level 1 The aim is to link all the machines in each level. It sounds easy enough, but if you're not an expert, it can be hard to find the information you need. So click on the next page and let's take a look at how it all works :) [PreviousCPP04 (doing)chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp04-doing) [NextTheorychevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_toupper | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#subject) Subject Copy TOUPPER(3) (simplified) NAME toupper -- lower case to upper case letter conversion SYNOPSIS int toupper(int c); DESCRIPTION The toupper() function converts a lower-case letter to the corresponding upper-case letter. The argument must be representable as an unsigned char or the value of EOF. RETURN VALUES If the argument is a lower-case letter, the toupper() function returns the corresponding upper-casse letter if there is one; otherwise, the argument is returned unchanged. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#understandable-explanation) Understandable explanation I don't think I'll need to explain with more details what this function does, the man is pretty self-explanatory on this point. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#hints) Hints ft\_toupper.c Copy int ft_toupper(int c) { if (/* c is lower-case letter */) return (/* corresponding upper-case letter */); return (c); } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#commented-solution) Commented solution chevron-rightft\_toupper[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#ft_toupper) [Previousft\_strlcatchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat) [Nextft\_tolowerchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper#commented-solution) sun-brightdesktopmoon ft\_toupper.c Copy #include "libft.h" int ft_toupper(int c) { /* this checks if the character is a lower-case letter * with the decimal ASCII values (97 => a; 122 => z) */ if (c >= 97 && c <= 122) /* in the ASCII table, upper-case letter are indexed 32 * less than lower-case letter, so to get the corresponding * upper-case letter, we substract 32 to the lower-case * letter */ return (c - 32); /* As said in the man, if the character is not a lower-case * letter, the argument is returned unchanged, that's why we * return c directly */ return (c); } sun-brightdesktopmoon --- # ft_isprint | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#subject) Subject Copy ISPRINT(3) (simplified) NAME isprint -- printing character test (space character inclusive) SYNOPSIS int isprint(int c) DESCRIPTION The isprint() function tests for any printing character, including space. The value of the argument must representable as an unsigned char or the value of EOF. RETURN VALUES The isprint() function returns zero if the character tests false and returns non-zero if the character tests true. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#understandable-explanation) Understandable explanation For this function, the man is pretty self-explanatory, but I'll give more details (i.e. what are the printing characters). The `isprint()` function returns a non-zero value if the character passed as an `int` parameter is a printing character. If the character is not a printing character, the `isprint()` function returns `0`. The printing characters are all character between decimal 32 and decimal 126. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#commented-solution) Commented solution chevron-rightft\_isprint[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#ft_isprint) [Previousft\_isasciichevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isascii) [Nextft\_strlenchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint#commented-solution) sun-brightdesktopmoon ft\_isprint.c Copy int ft_isprint(int c) { if (/* c is between 32 and 126 */) return (/* non-zero value of your choice */); return (0); } ft\_isprint.c Copy #include "libft.h" int ft_isprint(int c) { /* check if c is between decimal 32 and decimal 126 (inclusive) */ if (c >= 32 && c <= 126) return (c); // if we reach this point, c will be a non-zero value. return (0); } sun-brightdesktopmoon --- # ft_putnbr_fd | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#subject) Subject Copy FT_PUTNBR_FD (simplified) NAME ft_putnbr_fd -- write an int on a specified file descriptor SYNOPSIS void ft_putnbr_fd(int n, int fd); DESCRIPTION ft_putnbr_fd() writes the int n on the file descriptor fd PARAMETERS n: int to write fd: file descriptor on which to write RETURN VALUES ft_putnbr_fd() does not return anything AUTHORIZED EXTERNAL FUNCTIONS write(2) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#understandable-explanation) Understandable explanation This function works the same way as the `ft_putnbr()` function you had to do during the Piscine, it also takes the `fd` parameter, like `ft_putchar_fd()`, `ft_putstr_fd()`, `ft_putendl_fd()`. I think that going from here you should be able to build it. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#hints) Hints Don't forget that the character `0` is not code `0` in the `ASCII` table, I think you can take a look at your Piscine code ([`C05 - Ex04`arrow-up-right](https://github.com/Laendrun/piscine42/blob/main/c04/ex02/ft_putnbr.c) ), it works the same. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#commented-solution) Commented solution chevron-rightft\_putnbr\_fd[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#ft_putnbr_fd) [Previousft\_putendl\_fdchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putendl_fd) [NextBonus functionschevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/bonus-functions) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_putnbr_fd#commented-solution) sun-brightdesktopmoon ft\_putnbr\_fd.c Copy #include "libft.h" void ft_putnbr_fd(int n, int fd) { /* this checks for INT_MIN as INT_MAX is not * just INT_MIN * -1, so if we have INT_MIN, we can * directly write it out */ if (n == -2147483648) write(fd, "-2147483648", 11); /* if the number is less than 0, we have to write a '-' * followed by the number, so we write the '-' * then we multiply the number by -1 to make it positive * and we call the ft_putnbr_fd function with the positive * number */ else if (n < 0) { write(fd, "-", 1); n = -n; ft_putnbr_fd(n, fd); } else { /* here the number will be positive * the first thing we have to do is transform the * number into each of its digit * we do that by calling the function again with the * number / 10, that removes one digit from the end * of it since its an integer division * once we have done that, we can call the function * with the number % 10 to get the remainder of the * itneger division, that way we get each digit. * if the number we send to the function is still greater * than zero, we make the same thing, call the function * with the number divided by 10, then again with * with the number modulo 10 */ if (n > 9) { ft_putnbr_fd(n / 10, fd); ft_putnbr_fd(n % 10, fd); } else { /* if we get here, this means n is only one digit * when n is only one digit, we can convert it to * its corresponding character in the ASCII table * and write it. * as for the other functions, we set the first * parameter of the write function to fd */ digit = n + 48; write(fd, &digit, 1); } } } sun-brightdesktopmoon --- # ft_strtrim | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#subject) Subject Copy FT_STRTRIM (simplified) NAME ft_strtrim -- trims character set from string SYNOPSIS char *ft_strtrim(const char *s1, const char *set); DESCRIPTION Allocate (with malloc(3)) and returns a copy of s1, without the characters specified in set at the beginning and the end of s1. PARAMETERS s1: string to trim set: characters to trim RETURN VALUES ft_strtrim() returns a trimmed copy of s1; NULL if the memory allocation failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#understandable-explanation) Understandable explanation The `ft_strtrim()` function takes a string and trims it. What does trimming mean you might ask ? Let me explain. Trimming means removing the characters specified in the `set` string from the start AND the end of the string `s1`, without removing the characters from the `set` that are in the middle of `s1`. If we have the string `ababaaaMy name is Simonbbaaabbad` and our set is `ab`, we'll get this result out of the `ft_strtrim()` function : `My name is Simon`. We removed every `a` and `b` from the start and the end of `s1`, without touching at the a in the middle of `s1`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#hints) Hints We have to remove characters from the start AND the end of s1, so why don't we just loop over the string, advance while we have a character to remove. And then, do the same thing from the end of the string, leaving us with a start and an end index for our trimmed string. That's basically how I did it, and how my code works. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#commented-solution) Commented solution chevron-rightft\_strtrim[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#ft_strtrim) [Previousft\_strjoinchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strjoin) [Nextft\_splitchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim#commented-solution) sun-brightdesktopmoon ft\_strtim.c Copy #include "libft.hss" static int to_trim(const char *set, char c); static char *new_str(const char *s1, size_t start, size_t end); char *ft_strtrim(const char *s1, const char *set) { int i; int j; i = 0; j = ft_strlen(s1) - 1; /* if the string has a length of 0, we don't have anything * to trim, so we return an empty string that will be freeable */ if (ft_strlen(s1) == 0) return (ft_strdup("")); /* we first loop from the start of the string until we find the first * character that is not part of the set to trim */ while (to_trim(set, s1[i])) i++; /* we then do the same but from the end of the string this time. */ while (to_trim(set, s1[j])) j--; /* Now, that is what the values correspond to : * i : the start index of the trimmed string in the full string * j : the end index of the trimmed string in the full string * Here what the values would be with the example I talked about * above. * s1 : "ababaaaMy name is Simonbbaaabbad" * ft_strlen(s1) : 33 * after looping both ways, we have this : * i : 8 * j : 23 * but since we don't pass the end index, we pass the length of * the new string we have to some "maths" * j - (i - 1) : 23 - (8 - 1) = 23 - 7 = 16 */ return (new_str(s1, i, j - (i - 1)); } /* this is a function helper, it creates and allocates a new * string based on the three input passed as parameter */ static char *new_str(const char *s1, size_t start, size_t len) { char *str; size_t i; /* first, we check if the len of the string to create is 0 * or if the start of the new string is after the end of the * original string * if that is the case, we call ft_strdup to create an empty string * that can be freed later */ if (len <= 0 || start >= ft_strlen(s1)) return (ft_strdup("")); /* we then call ft_calloc to allocate enough memory for the new * string plus the NUL-terminating character * we use calloc instead of malloc so we don't have to think about * NUL-terminating the string at the end of our function */ str = ft_calloc(len + 1, sizeof(char)); if (!str) return (NULL); i = 0; /* looping over i while it is smaller than the length of * our new string */ while (i < len) { /* here we copy the content of s1 at index start + i into * our new string at index i, why is that ? * try to find by yourself, there is also a schema below to * explain this. */ str[i] = s1[start + i]; i++; } /* returning the new string that we created */ return (str); } /* This helper function return 1 if the character c is part of the * set of characters to trim and 0 if it is not part of it */ static int to_trim(const char *set, char c) { int i; i = 0; /* looping over the whole set so that we check the character c * against every character in the set of characters to trim */ while (set[i]) { if (c == set[i]) return (1); i++; } return (0); } sun-brightdesktopmoon --- # ft_memset | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#subject) Subject Copy MEMSET(3) (simplified) NAME memset -- fill a byte string with a byte value SYNOPSIS void *memset(void *b, int c, size_t len); DESCRIPTION The memset() function writes len bytes of value c (converted to an unsigned char) to the string b. RETURN VALUES The memset() function returns its first argument. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#understandable-explanation) Understandable explanation As the man description says, this function writes `len` bytes of value `c` to the string `b`. The value of `c` will be converted to an `unsigned char`, so to set this value in the `b` string, we'll have to convert the `b` string to a pointer to `unsigned char`. But remember the return value, we have to return the first parameter of the function, the `void *b` string. So how do we convert this parameter without changing the original one ? Think about temporary variables. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#hints) Hints To build this function, we'll have to declare a temporary variable, an `unsigned char *`. We'll then make all our manipulation on this pointer, without touching the original `void *b` string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#commented-solution) Commented solution chevron-rightft\_memset[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#ft_memset) [Previousft\_strlenchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen) [Nextft\_bzerochevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset#commented-solution) sun-brightdesktopmoon ft\_memset.c Copy void *ft_memset(void *b, int c, size_t len) { /* declare a temporary unsigned char * */ /* make this temporary variable equals to void *b converted to unsigned char */ /* loop on the temporary variable while we didn't reach len */ /* in that loop, set the current byte equal to c converted to unsigned char */ /* return void *b */ } ft\_memset.c Copy #include "libft.h" void *ft_memset(void *b, int c, size_t len) { /* declaring our temporary pointer */ unsigned char *tmp_ptr; /* making our temporary pointer equal to b converted to unsigned char * */ tmp_ptr = (unsigned char *) b; /* looping on our temporary pointer while we didn't reach len */ while (len > 0) { /* assigning the unsigned char value of c to the current byte in our temporary pointer */ *(tmp_ptr++) = (unsigned char) c; /* reducing the len by one so we only set len bytes */ len--; } /* return the function's first parameter, void *b */ return (b); } sun-brightdesktopmoon --- # ft_tolower | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#subject) Subject Copy TOLOWER(3) (simplified) NAME tolower -- upper case to lower case letter conversion SYNOPSIS int tolower(int c); DESCRIPTION The tolower() function converts an upper-case letter to the corresponding lower-case letter. The argument must be representable as an unsigned char or the value of EOF. RETURN VALUES If the argument is an upper-case letter, the tolower() function returns the corresponding lower-case letter if there is one; otherwise, the argument is returned unchanged. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#understandable-explanation) Understandable explanation I don't think I'll need to explain with more details what this function does, the man is pretty self-explanatory on this point. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#hints) Hints ft\_tolower.c Copy int ft_tolower(int c) { if (/* c is an upper-case letter */) return (/* corresponding lower-case letter */); return (c); } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#commented-solution) Commented solution chevron-rightft\_tolower[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#ft_tolower) [Previousft\_toupperchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper) [Nextft\_strchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower#commented-solution) sun-brightdesktopmoon ft\_tolower.c Copy #include "libft.h" int ft_tolower(int c) { /* this checks if the character is an upper-case letter * with the decimal ASCII values (65 => A; 90 => Z) */ if (c >= 65 && c <= 90) /* In the ASCII table, upper-case letters are indexed 32 * less than lower-case letters, so to get the * corresponding lower-case letter, we add 32 to the * upper-case letter */ return (c + 32); /* As said in the man, if the character is not an upper-case * letter, the argument is returned unchanged, that's why we * return c directly */ return (c); } sun-brightdesktopmoon --- # ft_isalpha | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#subject) Subject Copy ISALPHA(3) (simplified) NAME isalpha -- alphabetic character test SYNOPSIS int isalpha(int c) DECRIPTION The isalpha() function tests for any character for which isupper(3) or islower(3) is true. The value of the argument must be resprensentable as an unsigned char or the value of EOF. RETURN VALUES The isalpha() function return zero if the character tests false and returns non-zero if the character tests true. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#understandable-explanation) Understandable explanation For this function, the man is self-explanatory, but I'll still explain it in other words. The `isalpha()` function returns a non-zero value if the character passed as an `int` parameter is an alphabetical letter (lowercase or uppercase). If the character is not alphabetical, the `isalpha()` function returns `0`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#commented-solution) Commented solution triangle-exclamation Come on ! You really need the code for that function ? chevron-rightft\_isalpha[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#ft_isalpha) [PreviousLIBC functionschevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions) [Nextft\_isdigitchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isdigit) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isalpha#commented-solution) sun-brightdesktopmoon ft\_isalpha.c Copy int ft_isalpha(int c) { if (/* c value is one of the lowercase letter in the ASCII table or if c value is one the uppercase letter in the ASCII table*/) return (/* non-zero value of your choice */); return (0); } ft\_isalpha.c Copy #include "libft.h" int ft_isalpha(int c) { /* the first part of the condition checks if c is uppercase */ /* the second part of the condition checks if c is lowercase */ if ((c >= 65 && c <= 90) || (c >= 97 && <= 122)) return (c); // here I'm returning c, as if it's alphabetical it'll be non-zero return (0); // if we reach this point, c isn't alphabetical } sun-brightdesktopmoon --- # Exam Rank 05 | Guide This exam is about C++. 42 will test you on this new (and rather familiar) programming language you've just learned. It's not tricky, but it's pretty time-consuming and you'll need to read the subjects carefully! There are 3 modules. Let's take a look at each of them PS : Our reference for this exam it's this github : [https://github.com/JCluzet/42\_EXAM/tree/main/.subjects/STUD\_PART/exam\_05arrow-up-right](https://github.com/JCluzet/42_EXAM/tree/main/.subjects/STUD_PART/exam_05) [PreviousExam Rank 04chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-04) [NextModule 0chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-05/module-0) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Team | Guide This gitbook was written and created by Simon Aeby (saeby) & Laura Fabbiano (lfabbian) during their Cursus at the 42 School in Lausanne. If you want to contact us, do so :-) [LinkedIn - Laura Fabbianoarrow-up-right](https://www.linkedin.com/in/laura-fabbiano/) & [Laura - Githubarrow-up-right](https://github.com/thebrisly) & [Laura (aka Brisly)'s twitterarrow-up-right](https://twitter.com/TheBrisly) [LinkedIn - Simon Aebyarrow-up-right](https://www.linkedin.com/in/simon-aeby/) & [Laendrun - Githubarrow-up-right](https://github.com/Laendrun) & [Simon's Telegramarrow-up-right](https://t.me/Laendrun) [PreviousModule 0chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-05/module-0) Last updated 1 year ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_strlcpy | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#subject) Subject Copy STRLCPY(3) (simplified) NAME strlcpy -- size-bounded string copying SYNOPSIS size_t strlcpy(char *dst, const char *src, size_t dstsize); DESCRIPTION The strlcpy() function copy strings with the same input parameters and output result as snprintf(3). It is designed to be safer, more consistent, and less error prone replacement for the easily misused function strncpy(3) strlcpy() take the full size of the destination buffer and guarantee NUL-termination if there is room. Note that room for the NUL should be included in dstsize. Also note that strlcpy() only operate on true ''C'' strings. This means that for strlcpy() src must be NUL-terminated. strlcpy() copies up to dstsize - 1 characters from the string src to dst, NUL-terminating the result if dstsize is not 0. If the src and dst strings overlap, the behavior is undefined. RETURN VALUES The strlcpy() function return the total length of the strings it tried to create. That means the length of src. If the return value is >= dstsize, the output string has been truncated. It is the caller's responsibility to handle this. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#understandable-explanation) Understandable explanation What this function does is pretty simple in that it's made to copy one string to another but with a small catch, it **always** NUL-terminate the string. If you give a `dstsize` long enough to NUL-terminate the string without truncating it, `strlcpy()` will simply copy the string, as you'd do with `strcpy()`. If you don't give a `dstsize` long enough, it will copy `dstsize - 1` characters from the source into the destination, adding the NUL-terminating character after that. The `strlcpy()` function **always** returns the length of the string that it tried to create, this is the length of `src`, even if you have to truncate the string to NUL-terminate it. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#hints) Hints I implemented this the same way it is implemented in the Apple's C version. Check the sources for the link to the page. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#commented-solution) Commented solution chevron-rightft\_strlcpy[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#ft_strlcpy) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#sources) Sources [Apple OpenSource strlcpy implementationarrow-up-right](https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/arm/strlcpy.c.auto.html) [Previousft\_memmovechevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove) [Nextft\_strlcatchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#commented-solution) * [Sources](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy#sources) sun-brightdesktopmoon ft\_strlcpy.c Copy size_t ft_strlcpy(char *dst, const char *src, size_t dstsize) { /* get the length of src */ /* check if dstsize is big enough to accomodate src length * plus the NUL character */ /* copy the whole src into dst */ /* else */ /* copy dstsize - 1 characters into dst */ return (/* length of src */); } ft\_strlcpy.c Copy #include "libft.h" size_t ft_strlcpy(char *dst, const char *src, size_t dstsize) { size_t src_len; /* getting the length of src with our ft_strlen function */ src_len = ft_strlen(src); /* checking if dstsize is big enough to accomodate src_len plus * the terminating NUL character */ if (src_len + 1 < dstsize) /* using ft_memcpy to copy the source into the destination */ ft_memcpy(dst, src, src_len + 1); /* if dstsize is not big enough, we have to truncate the string * when copying it * note that we also check if dstsize is 0, if that is the case * we don't have to copy anything, so we just skip this part by * not entering the condition */ else if (dstsize != 0) { /* we also use ft_memcpy, but instead of giving it * src_len + 1 as a maxsize, we give it dstsize - 1 */ ft_memcpy(dst, src, dstsize - 1); /* we then NUL-terminate the string */ dst[dstsize - 1] = 0; } /* finally, we return the original length of the src */ return (src_len); } sun-brightdesktopmoon --- # P2P Evaluation - Questions | Guide triangle-exclamation Be careful, the first check that the student is going to do is checking that in your git repo there is only the signature of your virtual machine and NOTHING else. The signature must be identical as the one on your VM at the time of the evaluation (if you change something on your VM afterwards, the signature will be different). [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions#theoretical-questions) Theoretical questions --------------------------------------------------------------------------------------------------------------------------------------------- Here are the **theoretical questions** you will be asked during the evaluation: * How does a virtual machine work ? And what its purpose ? * Wh did you choose Debian or CentOS ? * What's the difference between Debian and CentOS ? * If you chose Debian: what's the difference between aptitude, apt and what's APPArmor ? * If you chose CentOS: what's SELinux and DNF ? * What the advantages/disadvantages of a strong password policy ? What can you say about its implementation ? * What's a partition ? And more generally how does LVM (Logical Volume Management) work ? * What's sudo ? * What's an UFW and what's the value of using it ? * What's SSH (Secure Shell) and what's the value of using it ? * What is cron ? Everything (and even more than necessary) is explained here: [📠What's a virtual machine ?chevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/whats-a-virtual-machine) [📠Install your virtual machinechevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine) [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions#practical-questions) Practical questions ----------------------------------------------------------------------------------------------------------------------------------------- And here are the **practical questions** that you will be asked to demonstrate and the command that you need to write to get to the answer: * Check that the signature contained is identical to that of the ".vdi" file of the virtual machine to be evaluated. 1. Open iTerm and type `cd` 2. Then type `cd sgoinfre/students//` 3. Then type `shasum VirtualBox.vdi` (or any other name that your VM has .vdi) * During the evaluation a script must display information every 10 minutes ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FELWAEe1hW58NJ6jHOnPQ%252Fimage.png%3Falt%3Dmedia%26token%3D3b1e68cf-65d5-4ece-9629-7ea424e0d539&width=768&dpr=3&quality=100&sign=3db2f0be&sv=2) Script that should appear every 10 minutes * The machine should not have a graphical environment at launch. * A password is requested before attempting to connect to this machine. * You need to connect with an user. The user must not be root. * Check that the UFW service is started * `sudo ufw status` * Check that the SSH service is started * `sudo systemctl status ssh` ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FaMQldwLnoWbjxqosCgiZ%252Fimage.png%3Falt%3Dmedia%26token%3Dc05bfc9d-6b01-4040-adde-60637775dc70&width=768&dpr=3&quality=100&sign=a66b7622&sv=2) you will find the status of the ssh service * Check that the operating system is Debian or CentOS (you can check it on the information script that is displayed every 10 minutes) * Check that a user with your login exists and is present on your VM. This user should belong to the groups "sudo" and "user42". * `getent group sudo` * `getent group user42` ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F9sbUiN3uMiOd2t0vYGic%252Fimage.png%3Falt%3Dmedia%26token%3D68f5b44c-bcbf-420d-88f4-bd0a460f6127&width=768&dpr=3&quality=100&sign=c576d3cb&sv=2) * Make sure that the rules imposed in the subject concerning the password policy have been put in place by following these steps: * Create a new user for the evaluator: `sudo adduser ` * He/She chooses a password * Create a new group named "evaluating": `sudo groupadd ` * Assign it to your new user (the evaluator's user): `sudo usermod -aG ` * Check the password expire rules: `sudo chage -l username` ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FzJYRhKR5uMfsMapBEyfl%252Fimage.png%3Falt%3Dmedia%26token%3Db6017a16-42c8-46ac-8253-36a6a63bf201&width=768&dpr=3&quality=100&sign=e64b8ce6&sv=2) your password rules should look like this * Check that this new user belongs to the "evaluating" group: `getent group evaluating` * Check that the hostname of the machine is correctly formatted as follows: login42 * `hostnamectl` * Modify this hostname by replacing the login with yours, then restart the machine (the new host name should be updated) * `hostnamectl set-hostname ` * change the hostname in this file too: `sudo nano /etc/hosts` * Restart your virtual machine * Restore the machine to the original name (just do the same thing as above) * Check the partitions for your VM (compare the output with the example in the subject). * `lsblk` * Check that the sudo program is properly installed on the virtual machine * `dpkg -l | grep sudo –` * Assign the evaluator's username to the "sudo" group * `sudo usermod -aG ` * Verify that the " /var/log/sudo/" folder exists and hast at least one file. * `cd /var/log/sudo/` * Check the contents of the files in this folder. You should see a history of the command used with sudo. * `ls` to check what contains this folder * `cat sudo.log` (this file is the file with the history of sudo commands) * Try to run a command via sudo and see if the files above have been updated * write whatever you want (i.e. sudo ls) and check if the new log has been added to the history by reading the file again (`cat sudo.log`) * Check that the UFW program is installed on your VM and that is working properly * `dpkg -l | grep ufw –` * List the active rule in UFW. A rule must exist for port 4242. * `sudo ufw status numbered` ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252Fg70XOpWpQAqqPzi2I65l%252Fimage.png%3Falt%3Dmedia%26token%3De688b4ef-3e19-4e91-a8ee-d088fadc79d2&width=768&dpr=3&quality=100&sign=57a280b5&sv=2) * Add a new rule to open port 8080 * `sudo ufw allow 8080` * Check that it has been added to the active rules * `sudo ufw status numbered` * Delete this new added rule. * `sudo ufw delete ` (mine is 2 and then i do it again with 3) * Check that the SSH service is installed and working on your virtual machine * `dpkg -l | grep ssh –` * Verify that the SSH service only uses port 4242 * Open your iTerm * write: `ssh your_user_id@127.0.0.1 -p 4242` * You are now connected on your VM through your terminall * Make sure that you cannot user SSH with the "root" user * Open your information script (the one that appears every 10 minutes) and explain it * if you followed the same github guide as me just type: `cd /usr/local/bin/` * and then: `cat monitoring.sh` chevron-rightExplanation for monitoring.sh[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions#explanation-for-monitoring.sh) * Change the cron and to make sure that your informative script appears now every minute * Type `sudo crontab -u root -e` to open the crontab and add the rule * New rule: `*/1 * * * *` * Restart the server one last time Okay... now you're ready to present your project :-) Good luck ! [PreviousInstall your virtual machinechevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/install-your-virtual-machine) [Nextft\_printfchevron-right](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf) Last updated 1 year ago * [Theoretical questions](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions#theoretical-questions) * [Practical questions](https://42-cursus.gitbook.io/guide/1-rank-01/born2beroot/p2p-evaluation-questions#practical-questions) sun-brightdesktopmoon Copy #!/bin/bash #>> you are telling your environment/ os to use bash as a command interpreter arc=$(uname -a) #uname displays information about the system and -a means all information #grep or "global regular expression print” is a command used in searching #and matching text files contained in the regular expressions #awk is a kind of super command with which you can do many things #for example awk '{ print $2; }' prints the second field of each line #The /proc/cpuinfo command provides information about pcpu=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l) vcpu=$(grep "^processor" /proc/cpuinfo | wc -l) #Provides each processor with an identifying number. #If you have one processor it will display a 0. #If you have more than one processor it will display #all processor information separately counting the processors #using zero notation. #The free command provides information about the total amount of the physical and #swap memory, as well as the free and used memory # -m displays the amount of memory in mebibytes fram=$(free -m | awk '$1 == "Mem:" {print $2}') #Display the free/unused memory uram=$(free -m | awk '$1 == "Mem:" {print $3}') #Diplay the used memory pram=$(free | awk '$1 == "Mem:" {printf("%.2f"), $3/$2*100}') #Display the usage rate as a percentage #The df command (short for disk free), is used to display information related to # file systems about total space and available space. fdisk=$(df -BG | grep '^/dev/' | grep -v '/boot$' | awk '{ft += $2} END {print ft}') udisk=$(df -BM | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} END {print ut}') pdisk=$(df -BM | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} {ft+= $2} END {printf("%d"), ut/ft*100}') cpul=$(top -bn1 | grep '^%Cpu' | cut -c 9- | xargs | awk '{printf("%.1f%%"), $1 + $3}') lb=$(who -b | awk '$1 == "system" {print $3 " " $4}') #here the goal is to know if your VM has dynamic partitions. #so if you have more than 0 partitions when you type the lsblk command #then you can display "yes lvmu=$(if [ $(lsblk | grep "lvm" | wc -l) -eq 0 ]; then echo no; else echo yes; fi) ctcp=$(ss -neopt state established | wc -l) ulog=$(users | wc -w) #hostname command displays the system hostname ip=$(hostname -I) # -I is used to get all IP(network) addresses mac=$(ip link show | grep "ether" | awk '{print $2}') cmds=$(journalctl _COMM=sudo | grep COMMAND | wc -l) #here you will call all the variables that you created above #and display eveything in an aesthetic way wall " #Architecture: $arc #CPU physical: $pcpu #vCPU: $vcpu #Memory Usage: $uram/${fram}MB ($pram%) #Disk Usage: $udisk/${fdisk}Gb ($pdisk%) #CPU load: $cpul #Last boot: $lb #LVM use: $lvmu #Connections TCP: $ctcp ESTABLISHED #User log: $ulog #Network: IP $ip ($mac) #Sudo: $cmds cmd" sun-brightdesktopmoon --- # Theory | Guide Before we begin, we need to understand three important concepts: the TCP (Transmission Control Protocol), the IP and the TCP/IP [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#tcp-transmission-control-protocol) TCP : Transmission Control Protocol ----------------------------------------------------------------------------------------------------------------------------------------------------- It ensures reliable data transfer by breaking information into small packets, sending them across the network, and ensuring they arrive in the correct order at the destination. It also handles error correction and congestion control, thus ensuring reliable data transmission. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#ip-internet-protocol) IP : Internet Protocol --------------------------------------------------------------------------------------------------------------------------- For this project we only use IPv4 (so i will not explain IPv6) : An IPv4-adress is a 32-bit number divided into 4 "blocks", each 8 bits. i.e.: Every device connected to the Internet is assigned a unique IP address, which is used to identify and locate it. It is responsible for addressing and routing data packets across the network. **An IP address is made up of two parts**: * one identifies the host, such as a computer or other device * the other identifies the network to which it belongs. \--> TCP/IP uses a subnet mask to separate the two (corresponds to the "mask" part under each device when doing an exercise) For example if the IP is 104.95.23.12, then the real representation in bits would be: 01101000.01011111.00010111.00001100 (the numbers can only go from 0 to 255). ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#private-networks) Private Networks * Private network IP address ranges are reserved for internal use within organizations or home/small office networks. * The following address ranges are reserved for private networks: * `10.0.0.0 - 10.255.255.255` * `172.16.0.0 - 172.31.255.255` * `192.168.0.0 - 192.168.255.255` * These ranges provide a large number of available IP addresses for private network infrastructure, allowing organizations to assign unique addresses to devices within their network without requiring public IP addresses. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#loopback-addresses) Loopback Addresses * The loopback address range is reserved for internal testing and communication within a device. * The loopback IP range is represented by `127.0.0.0 - 127.255.255.255.` * The loopback address 127.0.0.1, often referred to as "localhost," is used to access the device itself. It allows network applications running on the device to communicate with each other without accessing the external network. These reserved IP address ranges ensure that private networks can operate without conflicting with public IP addresses on the internet and provide convenient mechanisms for internal testing and communication within devices. There is some more special ip-ranges, but for this project, you only need to remember those above. [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#tcp-ip) TCP/IP --------------------------------------------------------------------------------------------- Together, TCP and IP provide a standardized and reliable means of transferring data between devices connected to the Internet, whether it's sending emails, browsing the web, downloading files, or streaming multimedia content. I recommend you to watch this small video (5min) just to understand better how everything works. TCP/IP in a nutshell And here is a little scheme that shows how everything works: ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252F2qcefg8C95CChuO8dwCN%252Fimage.png%3Falt%3Dmedia%26token%3Df948c415-175f-4010-a1d4-143775ea4bc3&width=768&dpr=3&quality=100&sign=20ca8aea&sv=2) Source: [https://www.internalpointers.com/post/introduction-tcp-ip-protocolarrow-up-right](https://www.internalpointers.com/post/introduction-tcp-ip-protocol) [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#undefined) ---------------------------------------------------------------------------------------- [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#masks-subnet-masks) Masks (subnet masks) ----------------------------------------------------------------------------------------------------------------------- A subnet mask, also known as subnetting mask or network mask, is a combination of bits used to divide an IP network into smaller subnets. It is used in conjunction with an IP address to determine the network address and the host address of a device on a network. A subnet mask defines the portion of the IP address that represents the network and the portion that represents the hosts within that network. \--> It is often represented as a series of numbers, typically in the form of four octets separated by periods, such as `255.255.255.0.` And as for IPs, we can represent this number in bits, which would give: 11111111.11111111.11111111.00000000 Through which `255.255.255.0` is a valid mask and `255.255.128.128` is **not** a valid mask. CIDR Dot-decimal Number of IP-addresses per subnet Usable IP-addresses per subnet Number of subnets /32 255.255.255.255 1 0 256 /31 255.255.255.254 2 0 128 /30 255.255.255.252 4 2 64 /29 255.255.255.248 8 6 32 /28 255.255.255.240 16 14 16 /27 255.255.255.224 32 30 8 /26 255.255.255.192 64 62 4 /25 255.255.255.128 128 126 2 /24 255.255.255.0 256 254 1 \---------------------------------------------------------------------------- [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#switches) Switches ------------------------------------------------------------------------------------------------- A switch is a networking device that allows you to connect multiple devices to the same network. Its main function is to receive incoming network packets and forward them to the appropriate destination device within its network. Imagine you have a network with multiple computers, printers, and other devices. Instead of connecting each device directly to the router or modem, you can connect them to a switch. The switch acts as a central point of connection, allowing devices to communicate with each other. When a device sends a data packet, such as a file or a request for information, the switch receives the packet and examines its destination address. Based on this information, the switch determines the appropriate port to which the packet should be forwarded. This ensures that the packet reaches the intended device and not unnecessary devices on the network. By using a switch, you can efficiently distribute network traffic and enable communication between devices. It helps to reduce network congestion and improve overall network performance. To see a working example, you can take a look at Level 3. Now that you know almost all the definitions, let's take a look at a few examples to help you get the hang of it! Click on the next page :) [PreviousNetPracticechevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice) [NextLevel 1 & 2chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/level-1-and-2) Last updated 1 year ago * [TCP : Transmission Control Protocol](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#tcp-transmission-control-protocol) * [IP : Internet Protocol](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#ip-internet-protocol) * [Private Networks](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#private-networks) * [Loopback Addresses](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#loopback-addresses) * [TCP/IP](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#tcp-ip) * [](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#undefined) * [Masks (subnet masks)](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#masks-subnet-masks) * [Switches](https://42-cursus.gitbook.io/guide/4-rank-04/netpractice/theory#switches) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_strlcat | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#subject) Subject Copy STRLCAT(3) (simplified) NAME strlcat -- size-bounded string concatenation SYNOPSIS size_t strlcat(char *dst, const char *src, size_t dstsize); DESCRIPTION The strlcat() function concatenate strings with the same input parameters and outuput result as snprintf(3). It is designed to be safer, more consistent, and less error prone replacements for the easily misused function strncat(3). strlcat() take the full size of the destination buffer and guarantee NUL-termination if there is room. Note that room for the NUL should be included in dstsize. Also note that strlcat() only operate on true ''C'' strings. This means that both src and dst must be NUL-terminated. strlcat() appends string src to the end of dst. It will append at most dstsize - strlen(dst) - 1 characters. It will then NUL-terminate, unless dstsize is 0 or the original dst string was longer than dstsize (in practice this should not happen as it means that either dstsize is incorrect or that dst is not a proper string). If the src and dst strings overlap, the behavior is undefinded. RETURN VALUES Like snprintf(3), strlcat() function return the total length of the string it tried to create. That means the initial length of dst plus the length of src. If the return value is >= dstsize, the output string has been truncated. It is the caller's responsibility to handle this. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#understandable-explanation) Understandable explanation What this function does is pretty simple in that it's made to concatenate two strings but with a small catch, it **always** NUL-terminate the string. If you give a `dstsize` long enough to NUL-terminate the resulting concatenated string without truncating it, `strlcat()` will simply concatenate the two string, as you'd do with `strcat()`. If you don't give a `dstsize` long enough, it will concatenate `dstsize - strlen(dst) - 1` characters, adding the NUL-terminating character after that. The `strlcat()` function **always** returns the length of the string it tried to create, this is the original length of `dst` plus the original length of `src`, even if you have to truncate the string to NUL-terminate it. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#hints) Hints I implemented this the same way it is implemented in the Apple's C version. Check the sources for the link to the page. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#commented-solution) Commented solution chevron-rightft\_strlcat[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#ft_strlcat) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#sources) Sources [Apple OpenSource strlcat implementationarrow-up-right](https://opensource.apple.com/source/Libc/Libc-997.1.1/string/strlcat.c.auto.html) [Previousft\_strlcpychevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy) [Nextft\_toupperchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_toupper) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#commented-solution) * [Sources](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcat#sources) sun-brightdesktopmoon ft\_strlcat.c Copy size_t ft_strlcat(char *dst, const char *src, size_t dstsize) { /* get the original length of src */ /* get the original length of dst */ /* if the length of dst is equal to dstsize */ /* simply return the the length of dst + the length of src */ /* if dstsize is big enough to accomodate both src and dst */ /* concatenate src at the end of dst */ /* else, concatenate dstsize character maximum */ return (/* length of src + length of dst */); } ft\_strlcat.c Copy #include "libft.h" size_t ft_strlcat(char *dst, const char *src, size_t dstsize) { size_t src_len; size_t dst_len; /* getting the original lenth of src and dst */ src_len = ft_strlen(src); dst_len = ft_strlen(dst); /* this check can be ommited if you implement the strnlen function */ if (dst_len >= dstsize) dst_len = dstsize; /* if the dst_len is equal to dst_size * this means that we don't need to concatenate anything since * the dst already contains the maximum number of characters */ if (dst_len == dstsize) return (dstsize + src_len); /* if dstsize is big enough to accomodate both src and dst */ if (src_len < dstsize - dst_len) /* we used ft_memcpy again, since it works directly on memory * addresses, we can offset the pointer of dst by dst_len so our * dst pointer is now set at the end of dst, then we tell ft_memcpy to * copy the content of src there for a maximum of src_len + 1 * character */ ft_memcpy(dst + dst_len, src, src_len + 1); else { /* in this case, we do the same thing as above, we offset the dst * pointer by dst_len and then we copy src there * this time, we copy dstsize - dst_len - 1 character */ ft_memcpy(dst + dst_len, src, dstsize - dst_len - 1); /* as with ft_strlcpy, we then NUL-terminate the string */ dst[dstsize - 1] = '\0'; } /* finally, we return the original length of src + dst */ return (dst_len + src_len); } sun-brightdesktopmoon --- # ft_strlen | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#subject) Subject Copy STRLEN(3) (simplified) NAME strlen -- find length of string SYNOPSIS size_t(const char *s); DESCRIPTION The strlen() function computes the length of the string s. RETURN VALUES The strlen() function returns the number of characters that precede the terminating NUL character. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#understandable-explanation) Understandable explanation For this function, the man is pretty self-explanatory on what the function does, but some things are new, we never seen some things before. The `strlen()` function returns the number of characters before the terminating `NUL` (`\0`) character of the string. #### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#what-does-this-mean) What does this mean ? If our string is `abcde\0`, `strlen()` will return `5`. The string we pass as parameter has the keyword `const` before it, this means we can't modify this string inside our function, since it's a constant value. The returned value of `strlen()` is of type `size_t`, what is it ? Let me explain. As said on [geeksforgeeks.orgarrow-up-right](https://geeksforgeeks.org/size_t-data-type-c-language) , the `size_t` data type is a type which is used to represent the size of objects in bytes and is therefore used as the return type by the `sizeof` operator. It is guaranteed to be big enough to contain the size of the biggest object the host system can handle. Basically the maximum permissible size is dependent on the compiler; if the compiler is 32 bit then it is simply a typedef (i.e., alias) for `unsigned int` but if the compiler is 64 bit then it would be a typedef for `unsigned long long`. The `size_t` data type is never negative. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#commented-solution) Commented solution triangle-exclamation Come on ! You wrote this function like a hundred times during the Piscine, you really need to see the code ? chevron-rightft\_strlen[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#ft_strlen) [Previousft\_isprintchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_isprint) [Nextft\_memsetchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memset) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlen#commented-solution) sun-brightdesktopmoon ft\_strlen.c Copy size_t ft_strlen(const char *s) { while( /* we are not reading \0 character */) /* increment a counter and read next char */ return (/* the counter */); } ft\_strlen.c Copy #include "libft.h" size_t ft_strlen(cont char *s) { /* usually we declare our counter as an int, but for this one * we'll declare it as a size_t since size_t is bigger than int */ size_t i; i = 0; /* we then iterate over all the characters in the s array * you might think there's no exit condition on this loop but * there is. If the character we read is \0 then the loop * condition will evaluate to false, therefore not going into * it again. */ while (s[i]) i++; /* as said in the hint, we return the counter, it will be equal * to the number of character before the terminating \0 * character */ return (i); } sun-brightdesktopmoon --- # ft_memcpy | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#subject) Subject Copy MEMCPY(3) (simplified) NAME memcpy -- copy memory area SYNOPSIS void *memcpy(void *dst, const void *src, size_t n); DESCRIPTION The memcpy() function copies n bytes from memory area src to memory area dst. If dstt and src overlap, behavior is undefined. Applications in which dst and src might overlap should use memove(3) instead. RETURN VALUES The memcpy() function returns the original value of dst ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#understandable-explanation) Understandable explanation The `memcpy` function copies maximum n bytes from `src` to `dst`. The man talks about memory overlapping, I'll explain this with details on the `memmove` function page. As for `memset` and `bzero` we'll need some temporary pointers to manipulate our data. This functions works like the `strcpy` function, except that `memcpy` accepts `void *` as parameters, so we can give it any type of pointer we want to copy. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#hints) Hints ft\_memcpy.c Copy void *ft_memcpy(void *dst, const void *src, size_t n) { /* declare a temporary pointer for dst */ /* declare a temporary pointer for src */ /* if src and dst are NULL, return dst */ /* make dst tmp pointer equal to dst converted to unsigned char * */ /* make src tmp pointer equal to src converted to unsigned char * */ /* loop over the dst tmp pointer while we didn't reach n */ /* set the current byte of dst tmp pointer equal to current byte of src tmp pointer */ /* return dst */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#commented-solution) Commented solution chevron-rightft\_memcpy[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#ft_memcpy) [Previousft\_bzerochevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_bzero) [Nextft\_memmovechevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy#commented-solution) sun-brightdesktopmoon ft\_memcpy.c Copy #include "libft.h" void *ft_memcpy(void *dst, const void *src, size_t n) { /* declaring both our temporary pointers */ unsigned char *tmp_dst; unsigned char *tmp_src; /* if both dst and src are NULL pointers we can directly return * dst since we won't do anything on it */ if (dst == (void *)0 && src == (void *)0) return (dst); /* assigning both our temporary pointers to the converted * values of the "real" pointers */ tmp_dst = (unsigned char *) dst; tmp_src = (unsigned char *) src; /* looping on both our temporary pointer until we reach * n bytes */ while (n > 0) { /* making current byte of tmp_dst = current byte of * tmp_src */ *(tmp_dst++) = *(tmp_src++); /* reducing n by one so we only copy n bytes */ n--; } /* returning original dst, not our temporary pointer */ return (dst); } sun-brightdesktopmoon --- # ft_strchr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#subject) Subject Copy STRCHR(3) (simplified) NAME strchr -- locate character in string SYNOPSIS char *strchr(const char *s, int c); DESCRIPTION The strchr() function locates the first occurence of c (converted to a char) in the string pointed to by s. The terminating null character is considered to be part of the string; therefor if c is '\0', the function locate the terminating '\0'. RETURN VALUES The function strchr() return a pointer to the located character, or NULL if the character does not appear in the string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#understandable-explanation) Understandable explanation The `strchr()` function searches for one character in a string. If it finds the character, it returns a pointer to the first occurence of this specific character. If it don't find any occurence of this character, it returns `NULL`. We also have to return a pointer to the character if the character is `\0`. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#hints) Hints ft\_strchr.c Copy char *ft_strchr(const char *s, int c) { /* loop over the whole string */ /* check if current character is equal to the one we have to find */ /* once we looped over the whole string, check again for the character * in case the character we have to find is '\0' */ /* if we didn't find c in the string, return NULL */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#commented-solution) Commented solution chevron-rightft\_strchr[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#ft_strchr) [Previousft\_tolowerchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_tolower) [Nextft\_strrchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr#commented-solution) sun-brightdesktopmoon ft\_strchr.c Copy #include "libft.h" char *ft_strchr(const char *s, int c) { unsigned int i; char cc, /* we convert c to a char as we got it as an int */ cc = (char) c; i = 0; /* looping over the whole string s */ while (s[i]) { /* if the current character is equal to cc * this means we found an occurence of c in the string * therefore, we return the address of the char as a char pointer */ if (s[i] == cc) return ((char *) &s[i]); /* if the current character is not equal to cc * we advance in the string */ i++; } /* once we looped over the whole string, if we didn't find an * occurence of cc, we have to check if cc is equal to '\0' * so we check once again if the current character is equal to cc * if this is the case, we return the address of '\0' as a char * pointer */ if (s[i] == cc) return ((char *) &s[i]); /* if we reach this point, this means we didn't find any * occurence of cc in the string so we return NULL as * stated in the man */ return (NULL); } sun-brightdesktopmoon --- # ft_split | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#subject) Subject Copy FT_SPLIT (simplified) NAME ft_split -- split a string into an array of words SYNOPSIS char **ft_split(const char *s, char c); DESCRIPTION Allocate (with malloc(3)) and returns an array of strings obtained by splitting s with the character c, used as delimiter. The returned array must be NUL-terminated. PARAMETERS s: string to split c: delimiter character RETURN VALUES ft_split() returns an array of strings resulting from the splitting of s; NULL if the memory allocation failed. AUTHORIZED EXTERNAL FUNCTIONS malloc(3) ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#understandable-explanation) Understandable explanation You might have heard some things about `ft_split()` but don't worry, I'll explain everything the best I can. circle-info There's a reason why we chose ft\_split as one of our Halloween costume 😂 The subject tells us that `ft_split()` must return an array of strings (=> an array of arrays, since strings are arrays of characters terminated by a NUL character). We can also phrase that as an array of words, we take the string `s` and we split it to get an array containing each words of it. Each word is separated by one or more `c`, that's our word delimiter. It's also said that our words array must be NUL-terminated. That means we have to allocate one more element in our array, that we can set to 0. By doing this we have an easy way to loop over our words array, the same as for a string: `while(words[i] != 0)`. The subject is not that hard to understand, the more complex thing is to your code do all that. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#hints) Hints We don't have enough line in a single function to write `ft_split()` so we'll have to write multiple functions. I'll quickly get over all the things we have to do to achieve a functioning `ft_split()` (the way I separate thing maybe is a sign ;)) * Count how many words there is in the string, depending on the delimiter * Allocate an array of arrays (words array) big enough to hold all words + 1 that we can set to 0 * Allocate a string for each words in our words array and copy the words in it * Free everything if we have a memory allocation error ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#commented-solution) Commented solution chevron-rightft\_split[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#ft_split) [Previousft\_strtrimchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_strtrim) [Nextft\_itoachevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_itoa) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions/ft_split#commented-solution) sun-brightdesktopmoon ft\_split.c Copy char **ft_split(const char *s, char c) { /* allocate an array big enough to hold all the words in s */ /* loop over the string and find the start of the word */ /* find the end of the word */ /* copy the world at the first free index in our words array */ /* return our words array */ } int word_count(/* whatever parameter you need */) { /* find and return the number of words in the string */ } void ft_free(/* whatever argument you need */) { /* free EVERYTHING you allocated */ /* each element of the array as well as the array */ } char *fill_word(/* whatever argument you need */) { /* allocate enough room for the word */ /* copy the word into the memory you allocated above */ /* return the allocated word */ } ft\_split.c Copy #include "libft.h" static int word_count(const char *str, char c); static char *fill_word(const char *str, int start, int end); static void *ft_free(char **strs, int count); /* you'll probably find another way to do this than what I did * it's not the best thing I did, but it works */ static void ft_initiate_vars(size_t *i, int *j, int *s_word); char **ft_split(const char *s, char c) { char **res; size_t i; int j; int s_word; ft_initiate_vars(&i, &j, &s_word); /* allocate a table big enough to hold all the words */ res = ft_calloc((word_count(s, c) + 1), sizeof(char *)); if (!res) return (NULL); /* loop over the whole string */ while (i <= ft_strlen(s)) { /* this check let's us find the index of the first * character of the word in the string. * s_word acts as a trigger so that we don't update * the index each time around the loop */ if (s[i] != c && s_word < 0) s_word = i; /* if we found the start of a word and then another * separator, we know that we reached the end of the word * this could also be the end of the string */ else if ((s[i] == c || i == ft_strlen(s)) && s_word >= 0) { /* j is the index of the word in our words array * so here we give the full string, the start index * of the word, and the current i, which is the end * of the word to the fill_word function which will * return an allocated word and set it to res[j] */ res[j] = fill_word(s, s_word, i); /* if fill_word failed to allocate memory * we have to free everything, so we call the ft_free * function with the words array and j which is the * number of word we already saved */ if (!(res[j])) return (ft_free(res, j)); /* when we saved our word, we reset our s_word to -1 * so it can trigger the next word when we go back * around the loop */ s_word = -1; j++; } i++; } return (res); } /* please find another way to do this, please */ static void ft_initiate_vars(size_t *i, int *j, int *s_word) { *i = 0; *j = 0; *s_word = -1; } static void *ft_free(char **strs, int count) { /* in this loop * we loop over each element of the words array * and we free it */ int i; i = 0; while (i< count) { free(strs[i]); i++; } /* when we freed every element * we can free the words array */ free(strs); return (NULL); } static char *fill_word(const char *str, int start, int end) { char *word; int i; i = 0; /* allocating enough memory to store the word */ word = malloc((end - start + 1) * sizeof(char)); if (!word) return (NULL); /* this loop copies the word from str to word */ while (start < end) { word[i] = str[start]; i++; start++; } /* we set the last character to 0 to NUL-terminate the string * and then we return the word * this word will be stored in our words array */ word[i] = 0; return (word); } static int word_count(const char *str, char c) { int count; int x; count = 0; x = 0; /* x is a trigger, we start counting the word only if it equals 0 * this let's us skip all the separators, as while it is a separator * the x variable will still be 0 * to make it clearer, we loop over the whole string, when we * encounter a character that is not a separator and our trigger is 0 * we add one to our word count and set our trigger to 1 so it will * not count another word until we find another separator * when we found a separator, we set our trigger to 0 again so that * we can count another word if there's one * the trigger helps us take care of the strings that are only * composed of separator */ while (*str) { if (*str != c && x == 0) { x = 1; count++; } else if (*str == c) x = 0; str++; } return (count); } sun-brightdesktopmoon --- # Exam Rank 03 | Guide This exam a little less complicated than the first one you did. Just do one of the two exercises you come across, and you're done. Here are the two exercises you may be asked to do: * [ft\_printf](https://42-cursus.gitbook.io/guide/1-rank-01/ft_printf) * This one is pretty simple, you need to implement only a part of the conversion from the original printf: `%x`, `%s` and `%d`. Pretty easy. * [get\_next\_line](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line) * A while back, this exercise wasn't compile with the `-D BUFFER_SIZE` flag, so it could be done on three (3) lines of code. But the subject changed, and now you have to build a complete `get_next_line`. Ant that's it ! Well... we won't lie to each other. If you get printf it's very fast and easy 😄 But if you get `get_next_line`, good luck ;) [Previoussort\_listchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list) [NextExam Rank 04chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-04) Last updated 3 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # CPP07 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#main-topics) Main topics Copy C++ templates I think it was the simplest CPP module to understand... It really is an intuitive concept that will save you a lot of time in your future projects! Let's directly dive into this topic 😄 ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#templates) Templates Templates in C++ allow you to write generic code that can work with different data types without duplicating code. Let's use a super simple example: **Imagine you want to create a function that swaps two values.** Without templates, you might create a separate function for each data type you want to swap, like this: Copy void swapIntegers(int& a, int& b) { int temp = a; a = b; b = temp; } void swapDoubles(double& a, double& b) { double temp = a; a = b; b = temp; } With templates, you can create a single function that works with various data types: * `template `: This line declares a template with a placeholder type `T`. It tells the compiler that we'll use `T` to represent different data types. * `void swapValues(T& a, T& b)`: This is the generic function that can swap values of any data type represented by `T`. It takes two references as parameters (to modify the original values) and uses `T` for the temporary variable. Now, you can use `swapValues` for integers, doubles, or any other data type without writing separate swap functions for each type: And...that's it, basically. You'll also need to implement class templates : ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#class-templates) Class templates **Class templates** in C++ are a way to **create generic classes that can work with different data types or objects**. They are similar in concept to function templates, but instead of creating generic functions, you create generic classes. Suppose you want to create a generic container class called `Box` that can hold different types of objects. You can use a class template to achieve this: * `template `: This line declares a class template with a placeholder type `T`. It tells the compiler that `T` will represent different data types or object types. * `class Box`: This is the declaration of the generic class named `Box` (a classical declaration - what you did in the other modules basically) * `T content;`: This is a member variable of type `T`, which represents the content that the `Box` can hold. * `Box(const T& item) : content(item) {}`: This is a constructor that takes an object of type `T` as a parameter and initializes the `content` member with that object. * `T getItem() const { return content; }`: This is a member function that retrieves the content of the `Box`. Now, you can use the `Box` class template to create instances for different types: Class templates are especially useful when you want to create reusable and type-safe container classes or data structures. Anyway. Templates aren't a difficult concept to understand, and you'll soon get the hang of it ! But make sure you understand them, because we're going to need them for module 8, which deals with containers... see you there! [PreviousCPP06 (to-do)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp06-to-do) [NextCPP08 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp08-to-do) Last updated 2 years ago * [Main topics](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#main-topics) * [Templates](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#templates) * [Class templates](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp07#class-templates) sun-brightdesktopmoon Copy template void swapValues(T& a, T& b) { T temp = a; a = b; b = temp; } Copy int main() { int x = 5, y = 10; double a = 2.5, b = 7.3; swapValues(x, y); // Swaps integers swapValues(a, b); // Swaps doubles return 0; } Copy template class Box { private: T content; public: Box(const T& item) : content(item) {} T getItem() const { return content; } }; Copy main() { Box intBox(42); // A Box that holds an integer Box doubleBox(3.14); // A Box that holds a double Box stringBox("Hello, World!"); // A Box that holds a string int intValue = intBox.getItem(); double doubleValue = doubleBox.getItem(); std::string stringValue = stringBox.getItem(); return 0; } sun-brightdesktopmoon --- # Exam Rank 04 | Guide The Rank 4 exam of 42 is quite simple: **just recreate a micro shell**. [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-04#subject) Subject ------------------------------------------------------------------------------------- `Allowed functions:` > malloc, free, write, close, fork, waitpid, signal, kill, exit, chdir, execve, dup, dup2, pipe, strcmp, strncmp Write a program that will behave like executing a shell command * The command line to execute will be the arguments of this program * Executable's path will be absolute or relative but your program must not build a path (from the PATH variable for example) * You must implement "|" and ";" like in bash * we will never try a "|" immediately followed or preceded by nothing or "|" or ";" * Your program must implement the built-in command cd only with a path as argument (no '-' or without parameters) * if cd has the wrong number of argument your program should print in STDERR "error: cd: bad arguments" followed by a '\\n' * if cd failed your program should print in STDERR "error: cd: cannot change directory to path\_to\_change" followed by a '\\n' with path\_to\_change replaced by the argument to cd * a cd command will never be immediately followed or preceded by a "|" * You don't need to manage any type of wildcards (\*, ~ etc...) * You don't need to manage environment variables ($BLA ...) * If a system call, except execve and chdir, returns an error your program should immediatly print "error: fatal" in STDERR followed by a '\\n' and the program should exit * If execve failed you should print "error: cannot execute executable\_that\_failed" in STDERR followed by a '\\n' with executable\_that\_failed replaced with the path of the failed executable (It should be the first argument of execve) * Your program should be able to manage more than hundreds of "|" even if we limit the number of "open files" to less than 30. Example that should work : chevron-rightOne solution (that inspired me)[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-04#one-solution-that-inspired-me) [https://github.com/shackbei/microshell-42/blob/main/microshell.carrow-up-right](https://github.com/shackbei/microshell-42/blob/main/microshell.c) [PreviousExam Rank 03chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-03) [NextExam Rank 05chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-05) Last updated 2 years ago sun-brightdesktopmoon Copy $>./microshell /bin/ls "|" /usr/bin/grep microshell ";" /bin/echo i love my microshell microshell i love my microshell $> >./microshell sun-brightdesktopmoon --- # CPP05 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp05#main-topics) Main topics Copy Repetition and Exceptions (try, throw & catch In this module, you'll learn how to create exceptions and then use them in your code. First, let's talk FOOD (because i'm hungry): **Imagine you're baking a cake.** 1. **Mixing Bowl:** This is where you combine ingredients, like mixing flour, eggs, and sugar. When you're blending things together, sometimes a small mistake can happen. 2. **Eggshell:** If you accidentally drop an eggshell into your mix, you wouldn't want it in your cake, right? So, you remove the eggshell to keep the cake perfect. Similarly, in code, when something unexpected occurs, you "throw away" the issue by sending an error message. 3. **Safety Net:** Now, picture having a safety net under your mixing bowl. If an eggshell falls in (an error occurs), the safety net catches it. Then you can decide what to do with the eggshell, like discarding it or acknowledging the mistake. In code, the safety net is like the "catch" block, helping you handle unexpected problems that occur during your program's execution. The metaphor may be a bit lame, but we're going to do exactly the same thing (well... almost) in C++. Let's take a very easy example and see step by step what it does to better understand these new concepts :) Here we have : Copy #include int main() { int dividend, divisor, result; std::cout << "Enter the dividend: "; std::cin >> dividend; std::cout << "Enter the divisor: "; std::cin >> divisor; try { if (divisor == 0) { throw "Division by zero is not allowed!"; // Throw an exception } result = dividend / divisor; std::cout << "Result: " << result << std::endl; } catch (const char* errorMessage) { std::cerr << "Error: " << errorMessage << std::endl; } return 0; } The code consists of **three main parts**. The "try" (miying bowl), "throw" (eggshell) & "catch"(safety net) blocks: 1. `try` block (l. 12-19): This is where you put code that might generate an exception. In this case, it checks if the divisor is zero, which would result in division by zero. 2. `throw (l.16 && also 14-17)`: If a condition inside the `try` block is met (in this case, if `divisor` is zero), the program throws an exception. This means it raises an error message ("Division by zero is not allowed!"). 3. `catch` block: This block "catches" the exception if it's thrown. It's like a safety net that handles the error. In this code, it catches exceptions of type `const char*`, which is a pointer to a string (the error message). So, in simple terms, if you try to divide by zero (which is not allowed in math), the code throws an exception with the error message. The `catch` block then catches this exception and displays the error message. If you enter valid numbers, the division is performed, and no exception is thrown. In this case, the code displays the result. This mechanism helps you gracefully handle errors and prevent your program from crashing when unexpected issues occur. And... that's about it. All CPP05 exercises are about playing with exceptions. **You'll also have to create your own exceptions**: class exceptions. It won't be too complicated, so I'll let you find the answer you to search on Internet. (Spoiler: the exception you create must inherit from the class... Exception ;-) ) [PreviousCPP (05-09) (to-do)chevron-left](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do) [NextCPP06 (to-do)chevron-right](https://42-cursus.gitbook.io/guide/5-rank-05/cpp-05-09-to-do/cpp06-to-do) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # Exam Rank 02 | Guide Here I will list every function that you can encounter during the Exam 02, their solutions, and as always, explanation of the code. circle-exclamation Some subject probably have changed since we took the exam. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02#exam) Exam The exam is separated in 4 stages, at each stage you have one of many functions to code. [Previousft\_transcendence (to-do)chevron-left](https://42-cursus.gitbook.io/guide/6-rank-06/ft_transcendence-to-do) [NextLevel 1chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_memmove | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#subject) Subject Copy MEMMOVE(3) (simplified) NAME memmove -- copy byte string SYNOPSIS void *memmove(void *dst, const void *src, size_t len); DESCRIPTION The memmove() function copies len bytes from string src to string dst. The two strings may overlap; the copy is always done in a non-destructive manner. RETURN VALUES The memmove() function returns the original value of dst. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#understandable-explanation) Understandable explanation The `memmove()` function does the same thing as the `memcpy()` function but this time, the copy is made, as said in the man, in a non-destructive manner. This means that both strings (src and dst) can overlap in memory and this function does not overwrite part of, or the entirety of the string when making the copy. #### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#what-is-memory-overlapping) What is memory overlapping ? I found a really good explanation on [stackexchange.comarrow-up-right](https://cs50.stackexchange.com/questions/14615/memory-overlap-in-c) so I'll copy it here to explain what is memory overlapping. > Suppose we have an array of 5 chars, where each char is a byte long > > Copy > > +++++++++++++++++++++++++++++++ > | 'a' | 'b' | 'c' | 'd' | 'e' | > +++++++++++++++++++++++++++++++ > 0x100 0x101 0x102 0x103 0x104 > > Now according to the man page of `memcpy`, it takes 3 arguments, a pointer to the destination block of memory, a pointer to the source block of memory, and the size of bytes to be copied. > > What if the destination is `0x102`, the source is `0x100` and the size is `3` ? Memory overlapping happens here. That is, `0x100` would be copied into `0x102`, `0x101` would be copied into `0x103` and `0x102` would be copied into `0x104`. > > Notice that we first copied into `0x102` then we copied from `0x102` which means that the value which was originally in `0x102` was lost as we overwrote it with the value we copied into `0x102` before we copy from it. So we would end up with something like > > Copy > > +++++++++++++++++++++++++++++++ > | 'a' | 'b' | 'a' | 'b' | 'a' | > +++++++++++++++++++++++++++++++ > 0x100 0x101 0x102 0x103 0x104 > > Instead of > > Copy > > +++++++++++++++++++++++++++++++ > | 'a' | 'b' | 'a' | 'b' | 'c' | > +++++++++++++++++++++++++++++++ > 0x100 0x101 0x102 0x103 0x104 > > How does a function like `memmove` take care of memory overlapping ? > > According to its man page, it first copies the bytes to be copied into a temporary array then pastes them into the destination block as oppose to a function like `memcpy` which copies directly from the source block to the destination block. That's for memory overlapping, it is also said that `memmove` copies the bytes to be copied into a temporary array then pastes them into the destination block. That's not the way I did it because as said in the subject of the LIBFT, we can't use `malloc()` for this function. The way I did it without using `malloc()`, is to first check if the 2 memory blocks are overlapping or not. If they are overlapping we'll copy from the end of the source memory block until the start. If they are not overlapping we'll copy "normally", from start to end. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#hints) Hints ft\_memmove ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#commented-solution) Commented solution chevron-rightft\_memmove[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#ft_memmove) [Previousft\_memcpychevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcpy) [Nextft\_strlcpychevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strlcpy) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memmove#commented-solution) sun-brightdesktopmoon ft\_memmove.c Copy void *ft_memmove(void *dst, const void *src, size_t len) { /* declare 2 temporary pointer for src and dst */ /* declare a counter */ /* check if both src and dst are NULL */ /* make dst tmp pointer equal to dst converted to char * */ /* make src tmp pointer equal to src converted to char * */ /* if src and dst are overlapping */ /* loop while len is greater than 0 and copy src into dst */ /* if src and dst are not overlapping */ /* loop while our counter is less than len and copy src into dst */ /* return dst */ } ft\_memmove.c Copy #include "libft.h" void *ft_memmove(void *dst, const void *src, size_t len) { /* declaring our 2 temporary pointers and our counter */ char *c_src; char *c_dst; size_t i; /* if both src and dst are NULL, we directly return NULL */ if (!dst && !src) return (NULL); /* assigning the converted values of src and dst to our temporary * pointers so that we don't touch the original values */ c_src = (char *) src; c_dst = (char *) dst; i = 0; /* checking if the address of the destination is greater than the * address of the source, if that's the case we'll copy from end to * start */ if (c_dst > c_src) while (len-- > 0) c_dst[len] = c_src[len]; /* if the address of the destination is not greater than the address * of the source, we'll copy from start to end, like we're used to */ else { while (i++ < len) c_dst[i] = c_src[i]; } return (dst); } sun-brightdesktopmoon --- # CPP03 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#main-topics) Main topics Copy Inheritance ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#inheritance) Inheritance Let's go and take a look at what _inheritance_ means. Inheritance is the capacity of a class to derive properties to another class. New classes are created from an existing class, the new class is called a _Child Class_ or _Derived Class_ and the class from which it was created is called the _Base Class_ or _Parent Class_. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#when-is-inheritance-useful) When is inheritance useful Let's say you have to create a little program to manage an inventory of vehicles. You'll go ahead and create a class for _Cars_, one for _Trucks_, one for _Motorbikes_, etc. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FA7cUAGQGHemO4KR8F8Q6%252Fcpp-03-classes-1.svg%3Falt%3Dmedia%26token%3Dc32d9285-0f7d-4579-b0b0-ba436bb6f060&width=768&dpr=3&quality=100&sign=17fe26eb&sv=2) Classes without inheritance example As you can see above, all the different types of vehicles have the same basic properties, but some might require additional properties. Do you really want to type the same properties over and over again each time you have to add a new vehicle type ? No, and that's what inheritance is for (amongst other things). ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FkcD4crZxVhyZwdwMfpOG%252Fcpp-03-classes-2.svg%3Falt%3Dmedia%26token%3D666dc1d6-cefc-44ee-bb1d-37fca793c113&width=768&dpr=3&quality=100&sign=7a292b63&sv=2) Classes with inheritance example Isn't it better like this ? What we are doing here is declaring a base class _Vehicle_, with some properties like any other class. Then, when we create our _Car_ class, we say it extends the available properties of _Vehicle_. If we declare a new _Car_, we can access and set all the properties from the base class since _Car_ extends it. Let's look at the following code. In that code, our _Car_ is a sub-class of _Vehicle_. We can access all the properties and functions of the _Vehicle_ class from any sub-class derived from it. If we want to create another vehicle type, we can simply create another class, i.e. _Truck,_ and do the same as for the _Car_ class. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#car-constructor) **Car Constructor** The `Car` class has its own constructor which does not take any parameters. Its main role is to initialize the `Car` class and set its type by calling the parent `Vehicle` class constructor with the hardcoded string "Car". This means that every time a `Car` object is created, it automatically gets the type "Car" through the `Vehicle` constructor. The `void` keyword indicates that no parameters are required for the `Car` constructor. The `Car` constructor uses an initialization list to call the parent `Vehicle` constructor with the predetermined type. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#access-specifier) Access Specifier Access specifiers play a crucial role in object-oriented programming as they control the visibility and accessibility of class members. There are three types of access specifiers: `public`, `protected`, and `private`. * `public` inheritance makes the public and protected members of the base class public and protected in the derived class respectively. This means that the same level of access is preserved in the derived class. * `protected` inheritance will make the public and protected members of the base class protected in the derived class. This restricts the access to these members outside the class hierarchy, while keeping them accessible within the class and its derived classes. * `private` inheritance will make both the public and protected members of the base class private in the derived class. This means that these members can no longer be accessed from objects of the derived class, only from within the derived class itself (essentially turning all inherited members into private members of the derived class). Here is an example illustrating different access specifiers in inheritance: It's essential to choose the right access specifier to ensure the encapsulation and proper hierarchical structure of your classes. This can have a significant impact on how your classes interact with one another and with the rest of your program. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#advanced-topics) Advanced topics #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#multiple-inheritance) Multiple Inheritance Multiple inheritance is a feature of some object-oriented programming languages in which a class can inherit characteristics and behaviors from more than one parent class. This allows for the creation of a new class that aggregates multiple behaviors from various classes. In C++, multiple inheritance can lead to complex hierarchies and the potential for the diamond problem, where a class inherits the same base class through multiple paths. Here's a simple syntax example in C++: When using multiple inheritance, it's essential to manage complexities and potential ambiguities that can arise, ensuring the correct functions or properties are accessed. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#diamond-inheritance-problem) Diamond Inheritance Problem You do remember that the last exercise in this module is called `DiamondTrap` right ? There might be a link that you can make here. Diamond inheritance occurs in Object-Oriented Programming when a subclass, or derived class, inherits from two classes that, in turn, inherit from a single base class. This creates a shape similar to a diamond when visualized in a class diagram. **Example:** When `SubDerived` tries to use `baseMethod`, the compiler may not be sure which version of `baseMethod` to use - the one from `Derived1` or the one from `Derived2`. This ambiguity is the essence of the diamond problem. **Virtual Inheritance as a Solution:** Virtual inheritance allows you to specify that only a single instance of the base class should be inherited by any derived classes, thus preventing multiple "copies" of the base class being included in the extended class hierarchies. Using virtual inheritance, `SubDerived` will only have one `baseMethod` inherited from the `Base` class, resolving the ambiguity and avoiding the diamond problem. You can find more information about derivation here on [IBMarrow-up-right](https://www.ibm.com/docs/en/zos/2.4.0?topic=reference-inheritance-c-only) , our here on [geekforgeeksarrow-up-right](https://www.geeksforgeeks.org/inheritance-in-c/) . [PreviousCPP02chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02) [NextCPP04 (doing)chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp04-doing) Last updated 2 years ago * [Main topics](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#main-topics) * [Inheritance](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#inheritance) * [Access Specifier](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#access-specifier) * [Advanced topics](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03#advanced-topics) sun-brightdesktopmoon Copy #include // Declaring our base Vehicle class class Vehicle { public: Vehicle(std::string type); std::string type; private: }; // Declaring our Car class that publicly extends our Vehicle class class Car : public Vehicle { public: Car(void); private: }; // Simple operator overload for output stream // as you can see, we say that we need a Vehicle on the right // side of the << operator std::ostream &operator<<(std::ostream &o, const Vehicle &v) { o << "This is a vehicle of type " << v.type; return (o); } // Constructors Vehicle::Vehicle(std::string type): type(type) {} Car::Car(void) : Vehicle("Car") {} int main(void) { Car car = Car(); std::cout << car << std::endl; return (0); } Copy Car::Car(void) : Vehicle("Car") {} Copy class Base { public: int publicVar; protected: int protectedVar; private: int privateVar; }; class PublicDerived : public Base { // publicVar is public // protectedVar is protected // privateVar is not accessible }; class ProtectedDerived : protected Base { // publicVar is protected // protectedVar is protected // privateVar is not accessible }; class PrivateDerived : private Base { // publicVar is private // protectedVar is private // privateVar is not accessible }; Copy class Base1 { public: void function1() {} }; class Base2 { public: void function2() {} }; class Derived : public Base1, public Base2 { // Inherits function1 from Base1 and function2 from Base2 }; int main() { Derived derivedObject; derivedObject.function1(); // From Base1 derivedObject.function2(); // From Base2 } Copy class Base { public: void baseMethod() {} }; class Derived1 : public Base { // Inherits baseMethod from Base }; class Derived2 : public Base { // Inherits baseMethod from Base }; class SubDerived : public Derived1, public Derived2 { // Attempts to inherit baseMethod from both Derived1 and Derived2 // This may cause ambiguity because baseMethod exists in two places in the hierarchy. }; Copy class Base { public: void baseMethod() {} }; class Derived1 : virtual public Base { // Virtually inherits baseMethod from Base }; class Derived2 : virtual public Base { // Virtually inherits baseMethod from Base }; class SubDerived : public Derived1, public Derived2 { // Inherits a single instance of baseMethod }; sun-brightdesktopmoon --- # Functions used | Guide Remember `printf` ? Yeah right you recoded it yourself, that's good, but for this project, you can use the `stdlib` one, the real one. And you also have access to a lot of other functions, but you **can't** use your `libft` for this project. Some of these functions are only used for the bonus part, I didn't used them so I'll let you search how to use them. For this project you'll have to compile your programm with the `-pthread` flag. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#usleep) usleep() Copy int usleep(useconds_t usec); `usleep()` is a function in the C standard library that causes the calling process to sleep for a specified number of microseconds. chevron-rightusleep() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#usleep-example) Copy #include #include int main(void) { printf("Sleeping for 500000 microseconds...\n"); usleep(500000); printf("Done sleeping.\n"); return 0; } ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#gettimeofday) gettimeofday() Copy int gettimeofday(struct timeval *restrict tv, struct timezone *restrict tz); The _**gettimeofday()**_ function gets the system’s clock time. The current time is expressed in elapsed seconds and microseconds since 00:00:00, January 1, 1970 (Unix Epoch). chevron-rightgettimeofday()[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#gettimeofday-1) Copy #include #include int main() { struct timeval current_time; gettimeofday(¤t_time, NULL); printf("seconds : %ld\nmicro seconds : %ld", current_time.tv_sec, current_time.tv_usec); return 0; } The 1st parameter is a pointer to a `timeval` structure. The `timeval` structure is defined as below in the `` header file. Copy struct timeval { time_t tv_sec ; //used for seconds suseconds_t tv_usec ; //used for microseconds } The second argument should **always** be set to `NULL`. This second argument is obsolete and is only there for backwards compatibility. You can find more information about **gettimeofday()** [herearrow-up-right](https://man7.org/linux/man-pages/man2/settimeofday.2.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_create) pthread\_create() The `pthread_create()` function starts a new thread in the calling process. The new thread starts execution by invoking `start_routine()`; `arg` is passed as the sole argument of `start_routine()`. You can find more information about `pthread_create()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_create.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_join) pthread\_join() The `pthread_join()` function waits for the thread specified by `thread` to terminate. If that thread has already terminated, then `pthread_join()` returns immediately. chevron-rightpthread\_create() & pthread\_join() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_create-and-pthread_join-example) In this example, we use the pthread\_create() function to create a new thread that is initiated with the function called thread(). We then wait for the thread to terminate before printing the return value of the thread. You can find more information about `pthread_join()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_join.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_init) pthread\_mutex\_init() The `pthread_mutex_init()` function initializes the mutex referenced by `mutex` with the attributes specified by `attr`. If `attr` is `NULL`, the default mutex attributes are used. When the `mutex` is successfully initialized, the mutex state becomes `initialized` and `unlocked`. chevron-rightpthread\_mutex\_init() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_init-example) The above example uses the `pthread_mutex_init()` function to initialize a new `mutex` that can be used from all threads that we want to. You can find more information about `pthread_mutex_init()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_mutex_destroy.3p.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_destroy) pthread\_mutex\_destroy() `The pthread_mutex_destroy()` function destroys the mutex object referenced by `mutex`. The `mutex` object becomes uninitialized and can be reinitialized with `pthread_mutex_init()` if needed. chevron-rightpthread\_mutex\_init() & pthread\_mutex\_destroy() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_init-and-pthread_mutex_destroy-example) You can find more information about `pthread_mutex_destroy()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_mutex_destroy.3p.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_lock) pthread\_mutex\_lock() The `pthread_mutex_lock()` function locks the mutex referenced by `mutex`. You can find more information about `pthread_mutext_lock()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_unlock) pthread\_mutex\_unlock() The `pthread_mutex_unlock()` function unlocks the mutex referenced by `mutex`. chevron-rightpthread\_mutex\_lock() & pthread\_mutex\_unlock() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_lock-and-pthread_mutex_unlock-example) You can find more information about `pthread_mutex_unlock()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html) . [PreviousUnderstand Philosopherschevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/understand-philosophers) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/building-the-thing) Last updated 3 years ago * [usleep()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#usleep) * [gettimeofday()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#gettimeofday) * [pthread\_create()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_create) * [pthread\_join()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_join) * [pthread\_mutex\_init()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_init) * [pthread\_mutex\_destroy()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_destroy) * [pthread\_mutex\_lock()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_lock) * [pthread\_mutex\_unlock()](https://42-cursus.gitbook.io/guide/3-rank-03/philosophers/functions-used#pthread_mutex_unlock) sun-brightdesktopmoon Copy int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg); Copy int pthread_join(pthread_t thread, void **retval); Copy The pthread_join() function waits for the thread specified by thread to terminate. If that thread has already terminated, then pthread_join() returns immediately. The thread specified by thread must be joinable. Copy #include #include #include void *thread(void *arg) { char *ret; printf("thread() entered with argument '%s'\n", arg); if ((ret = (char*) malloc(20)) == NULL) { perror("malloc() error"); exit(2); } strcpy(ret, "This is a test"); pthread_exit(ret); } main() { pthread_t thid; void *ret; if (pthread_create(&thid, NULL, thread, "thread 1") != 0) { perror("pthread_create() error"); exit(1); } if (pthread_join(thid, &ret) != 0) { perror("pthread_create() error"); exit(3); } printf("thread exited with '%s'\n", ret); } Copy int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); Copy #include int main(void) { pthread_mutex_t mutex; // Initializing the mutex pthread_mutex_init(&mutex, NULL); } Copy int pthread_mutex_destroy(pthread_mutex_t *mutex); Copy #include #incluce int main(void) { pthread_mutex_t mutex; // Initializing the mutex pthread_mutex_init(&mutex, NULL); printf("You can use the mutex from now on"); // Destroying the mutex pthread_mutex_destroy(&mutex); } Copy int pthread_mutex_lock(pthread_mutex_t *mutex); Copy int pthread_mutex_unlock(pthread_mutex_t *mutex); Copy #include #include int main(void) { pthread_mutex_t fork_mutex; pthread_mutex_init(&fork_mutex, NULL); pthread_mutex_lock(&fork_mutex); set_unavailable(fork); pthread_mutex_unlock(&fork_mutex); pthread_mutex_destroy(&fork_mutex); return (0); } sun-brightdesktopmoon --- # CPP02 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#main-topics) Main topics Copy Ad-hoc polymorphism, operator overloading and Orthodox Canonical class form Before diving into ad-hoc polymorphism and operator overloading, let's take a look at the new rules given in the subject of this module. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FDkWVEPQP6CrMf2nbrp8i%252FScreenshot%25202023-05-25%2520at%252020.40.15.png%3Falt%3Dmedia%26token%3D23f0f520-201c-4c68-9897-2174dd2e2ac4&width=768&dpr=3&quality=100&sign=999f71d2&sv=2) CPP02 - New rules Orthodox Canonical Form, oh man that sounds complicated and... it's actually not that difficult. It simply adds mandatory member functions to your classes, we'll see that in details in a few lines. The second new rule, maybe you already did that, if not, look at the examples below and I think you'll get the idea pretty quickly. Okay, so let's get to Orthodox Canonical Form... ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#orthodox-canonical-form) Orthodox Canonical Form As the subject says, to respect the OCF (Orthodox Canonical Form), you have 4 mandatory members functions, let's take an example of what it should look like: The class declaration itself is not that hard except maybe for this line: `Example &operator=(const Example& e);` When I first saw that I was like _Excuse me wtf,_ but it starts to make sense pretty quickly. It is "only" a way to tell your program how to act when you write the following code: In the 4 mandatory member functions, you already know at least 2 of them, the default constructor and the destructor. Let's take a quick look at what the two other do. First, the copy constructor. The copy constructor takes a reference to an object and constructs a new one based on the values of the referenced one. I think you get the gist, the name _copy constructor_ is pretty clear. Secondly, let's look at the assignment operator overload. > This is also connected to the _Operator overload_ main topic. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#a-d-hoc-polymorphism) Ad-hoc polymorphism I'm not insulting you, I promise. Let me explain. _What the f\*\*\* is ad-hoc polymorphism ?_ Remember that, like in C, C++ is a typed language, so if you write a function taking an `int` as parameter, you'll not be able to pass it a `unsigned int`. But, there's something you can do in C++ that you can't in C, called `function overloading`, and that's how ad-hoc polymorphism is built. First, try to compile the following C code. If everything's good, you should get an error like `main.c:4:6: error: conflicting types for 'print'` And that's totally normal, you have to functions with the same name but taking different argument types, and that's not possible in C. Now, let's try the following C++ code. And now... surprise, no errors at compile time, not in C++ and why is that ? That's because function overloading is authorised in C++. Function overloading allows us to define two or more function with the same name in the same scope. Ad-hoc polymorphisme works with function overloading, this will lead to code duplication. For each type you want your function to work with, you have to write it completely from 0 with another type. circle-info There's also something called `Parametric polymorphism`, but that's another topic for a later time (-> CPP07) ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#operator-overloading) Operator overloading And now, let's get to the last topic of this module, operator overloading. As you saw in the last part, you can overload function in C++ by defining two or more function with the same name. Now, I'll show you how you can overload operators like `=`, `>=`, `<=`, `==`, and a lot of others. I'll only show example with some operator overloads, the other types works mostly the same with a little twist in the declaration but I'll let you search for the specific twists needed when you reach exercise 02 of this module. As said before, I won't show you all the operator overload available (see below), but only the main ones and this gives you an idea of most of the declarations. A little Google search will get you to what you want easily now that you have the correct terms to look for. ![](https://42-cursus.gitbook.io/guide/~gitbook/image?url=https%3A%2F%2F2977649544-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fz2zo8aAL0o31034sj7J7%252Fuploads%252FmSxLAcMHgQ6Yzb52s2v3%252FScreenshot%25202023-05-26%2520at%252023.26.01.png%3Falt%3Dmedia%26token%3D7ede9f85-a5e9-4848-8751-30db76558a5d&width=768&dpr=3&quality=100&sign=a251f52c&sv=2) All the available operator that you can overload... - [cppreference.comarrow-up-right](https://en.cppreference.com/w/cpp/language/operators) #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#helper-script) Helper Script If you read through everything and got there, you deserve some kind of "treat", click [herearrow-up-right](https://github.com/Laendrun/ocf_script) to find a bash script that will generate the files and template the required functions for Orthodox Canonical Form automatically for you. [PreviousCPP01chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01) [NextCPP03chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp03) Last updated 2 years ago * [Main topics](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#main-topics) * [Orthodox Canonical Form](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#orthodox-canonical-form) * [Ad-hoc polymorphism](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#a-d-hoc-polymorphism) * [Operator overloading](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02#operator-overloading) sun-brightdesktopmoon example.hpp Copy #ifndef EXAMPLE_HPP # define EXAMPLE_HPP class Example { public: Example(void); Example(const Example& ex); Example &operator=(const Example& e); ~Example(void); } #endif main.cpp Copy #include "Example.hpp" int main(void) { Example a; Example b; a.num = 10; a.name = "Simon"; b = a; // What values should be equal to which ? // this is what the operator overload let's us define } Example.cpp Copy #include "Example.hpp" Example::Example(const Example& ex) : _val1(ex._val1) /* ... */ { return ; } Example.cpp Copy #include "Example.hpp" Example &Example::operator=(const Example& ex) { // in this case, we can't use the initialization list since // it's not a constructor function this->_val1 = ex._val1; return (*this); } main.c Copy #include void print(int i); void print(unsigned int j); int main(void) { int i = 10; unsigned int j = 100; print(i); print(j); return (0); } void print(int i) { printf("Value is: %d\n", i); } void print(unsigned int j) { printf("Value is: %u\n", j); } main.cpp Copy #include void print(int i); void print(unsigned int j); int main(void) { int i = 10; unsigned int j = 100; print(i); print(j); print(i, j); return (0); } void print(int i) { std::cout << "Value is: " << i << std::endl; } void print(unsigned int j) { std::cout << "Value is: " << j << std::endl; } void print(int i, unsigned int j) { std::cout << "Values are: " << i << " and " << j << std::endl; } Example.cpp Copy #include "Example.hpp" // Assignment operator Example &Example::operator=(const Example& ex) {...} // you already saw that one // Comparison operator (only one of the many available) bool Example::operator>(const Example& ex) { return (this->_val > ex._val); } // Arithmetic operator Example Example::operator+(const Exammple& ex) const { return (Example(this->_val + ex._val)); } // Output stream operator std::ostream &operator<<(std::ostream &o, const Example &ex) { o << "Value is: " << ex._val << std::endl; return (o); } sun-brightdesktopmoon --- # Functions used | Guide You are allowed to use several functions in this project. You already know some of them like write, ft\_printf (yours!), malloc, free and all the functions from your libft. However, other important functions that have never been used before will be **essential** to the success of this project. Let's look at them together. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#signal) signal() Copy sighandler_t signal(int signum, sighandler_t handler); The `signal` function in C is a way to specify a function, called a signal handler, to be called when a specific signal is received by a running program. A signal is a message from the operating system to a program indicating that some event has occurred. The `signal` function allows you to specify a function to be called when a particular signal is received, so that you can take some action in response to the signal. chevron-rightsignal() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#signal-example) Copy #include #include #include void signal_handler(int signum) { printf("Received SIGINT!\n", signum); exit(0); } int main() { // Set the signal handler for the SIGINT and SIGTERM signals // to the signal_handler function signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); while (1) { // Do some work here... } return 0; } In this example, we've set the signal handler for both the `SIGINT` and `SIGTERM` signals to the `signal_handler` function. The `SIGINT` signal is generated when the user presses `CTRL+C`, and the `SIGTERM` signal is generated when the program is terminated by the operating system (e.g. by running the `kill` command). When either of these signals is received, the `signal_handler` function will be called, and it will print a message to the console and exit the program. This example also demonstrates a common use case for the `signal` function: setting a signal handler to gracefully terminate a program when a certain signal is received. By setting a signal handler for the `SIGINT` and `SIGTERM` signals, we can ensure that the program will exit cleanly when it is terminated, rather than leaving resources in an undefined state. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigemptyset) sigemptyset() Copy int sigemptyset(sigset_t *set); The `sigemptyset` function is used to initialize a signal set to the empty set, which means that it does not contain any signals. Signal sets are used by some functions, such as `sigaction`, to define the signals to be processed. The `sigemptyset` function takes a pointer to a set of signals as an argument and empties this set by adding no signal to it. This function is often used in conjunction with the `sigaddset` function, which adds a specified signal to a signal set. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigaddset) sigaddset() Copy int sigaddset(sigset_t *set, int signum); This function allows to add a signal to a set of signals. The `sigaddset` function takes two arguments: a pointer to a set of signals and the number of the signal to add to the set. Here is an example of using `sigaddset` to add the signal SIGINT to a set of signals and `sigemptyset`: chevron-rightsigemptyset() & sigaddset() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigemptyset-and-sigaddset-example) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigaction) sigaction() The `sigaction` function in C is used to specify the action to be taken when a specific signal is received by a process. It is defined in the `signal.h` header file. The `signum` argument specifies the signal for which the action is being specified. The `act` argument is a pointer to a `struct sigaction` that specifies the action to be taken when the signal is received. The `oldact` argument is a pointer to a `struct sigaction` that is used to retrieve the previous action for the specified signal. chevron-rightsigaction() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigaction-example) In this example, the `signal_handler` function is specified as the action to be taken when the `SIGINT` signal is received. When the signal is received, the `signal_handler` function will be called, which will print a message to the console. The `sigemptyset` function is used to initialize the signal mask, which specifies the signals that should be blocked while the signal handler is executing. The `sa_flags` field is set to 0, which specifies the default behavior for the signal action. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#kill) kill() In C, the `kill` function **is a system call that sends a signal to a process**. It is defined in the `signal.h` header file. The `pid` argument specifies the process ID of the process you want to communicate with. The `sig` argument specifies the signal to be sent to the process. There are various signals that can be sent, each corresponding to a different purpose. For example, the `SIGKILL` signal is used to terminate processes that are unresponsive or stuck in an infinite loop. chevron-rightkill() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#kill-example) Here is an example of using the `kill` function to terminate a process with the `SIGKILL` signal: Note that using the `kill` function to terminate a process should generally be avoided, as it can leave resources allocated to the process in an undefined state. Instead, it is usually better to allow the process to terminate gracefully by providing it with an opportunity to clean up and release resources before exiting. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#getpid) getpid() In C, the `getpid` function **returns the process ID of the current process**. It is declared in the `unistd.h` header file. chevron-rightWhat are the process ID for?[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#what-are-the-process-id-for) In an operating system, a process is **an instance of a program that is being executed**. A process ID (PID) is a unique identifier assigned to each process by the operating system when it is created. Process IDs are useful for a variety of purposes in coding. Here are a few examples: 1. Identifying and tracking processes: As mentioned earlier, the process ID is a unique identifier for a process, so it can be used to identify and track specific processes within the system. 2. Sending signals to processes: The `kill` function in C allows you to send a signal to a process, and you can specify the process to send the signal to using the process ID. This can be useful for controlling and interacting with processes from your code. 3. Process communication: Process IDs can be used as a way for processes to communicate with each other. For example, one process might create a new process using the `fork` function, and then pass the child process's ID back to the parent process so that the parent can communicate with the child. 4. Debugging: Process IDs can be helpful in debugging, as they can be used to identify which processes are causing problems or behaving unexpectedly. Overall, process IDs are a useful tool for managing and interacting with processes in your code. chevron-rightgetpid() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#getpid-example) This program will print the process ID of the current process to the console. The process ID is a unique identifier assigned to each process by the operating system. It is used to identify and track processes within the system. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#pause) pause() `pause()` is a function in the C standard library that causes the calling process to sleep until a signal is received. The process remains blocked until a signal handler is executed or the signal is ignored chevron-rightpause() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#pause-example) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sleep) sleep() `sleep()` is also a function in the C standard library that causes the calling process to sleep for a specified number of seconds. chevron-rightsleep() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sleep-example) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#usleep) usleep() `usleep()` is a function in the C standard library that causes the calling process to sleep for a specified number of microseconds. chevron-rightusleep() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#usleep-example) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#exit) exit() `exit()` is a function in the C standard library that terminates the calling process immediately. It takes an integer argument that specifies the exit status of the process. A value of 0 indicates successful termination, while non-zero values indicate an error. chevron-rightexit() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#exit-example) And... that's it. You should be able to make some tests alone right now ;) If you don't know how to do it, see you in the next step. [PreviousUnderstand minitalkchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/understand-minitalk) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/building-the-thing) Last updated 1 year ago * [signal()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#signal) * [sigemptyset()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigemptyset) * [sigaddset()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigaddset) * [sigaction()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sigaction) * [kill()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#kill) * [getpid()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#getpid) * [pause()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#pause) * [sleep()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#sleep) * [usleep()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#usleep) * [exit()](https://42-cursus.gitbook.io/guide/2-rank-02/minitalk/functions-used#exit) sun-brightdesktopmoon Copy #include int main(void) { sigset_t signal_set; // Initialize an empty signal set sigemptyset(&signal_set); // Add SIGINT to the signal set sigaddset(&signal_set, SIGINT); Copy int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); Copy #include #include #include void signal_handler(int signum) { printf("Received signal %d\n", signum); } int main(void) { struct sigaction action; action.sa_handler = signal_handler; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGINT, &action, NULL); while (1) { // Do some work } return 0; } Copy int kill(pid_t pid, int sig); Copy #include #include #include int main() { pid_t pid = getpid(); // get the process ID of the current process int result = kill(pid, SIGKILL); // send the SIGKILL signal to the process if (result == 0) { printf("Process terminated successfully.\n"); } else { perror("Error terminating process"); } return 0; } Copy pid_t getpid(void); Copy #include #include int main(void) { pid_t pid; pid = getpid(); printf("The process ID is %d\n", pid); return 0; } Copy int pause(void); Copy #include #include int main(void) { printf("Entering pause...\n"); pause(); printf("Exiting pause.\n"); return 0; } Copy unsigned int sleep(unsigned int seconds); Copy #include #include int main(void) { printf("Sleeping for 3 seconds...\n"); sleep(3); // The program waits 3 seconds printf("Done sleeping.\n"); return 0; } Copy int usleep(useconds_t usec); Copy #include #include int main(void) { printf("Sleeping for 500000 microseconds...\n"); usleep(500000); printf("Done sleeping.\n"); return 0; } Copy void exit(int status); Copy #include #include int main(void) { printf("Exiting with status 0...\n"); exit(0); } sun-brightdesktopmoon --- # Module 0 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-05/module-0#subject) Subject : Copy Assignment name : cpp_module00 Expected files : Warlock.cpp Warlock.hpp -------------------------------------------------------------------------------- Make a Warlock class. It has to be in Coplien's form. It has the following private attributes : * name (string) * title (string) Since they're private, you will write the following getters : * getName, returns a reference to constant string * getTitle, returns a reference to constant string Both these functions will have to be callable on a constant Warlock. Create the following setter: * setTitle, returns void and takes a reference to constant string Your Warlock will also have, in addition to whatever's required by Coplien's form, a constructor that takes, in this order, its name and title. Your Warlock will not be able to be copied, instantiated by copy, or instantiated without a name and a title. For example : Warlock bob; //Does not compile Warlock bob("Bob", "the magnificent"); //Compiles Warlock jim("Jim", "the nauseating"); //Compiles bob = jim; //Does not compile Warlock jack(jim); //Does not compile Upon creation, the Warlock says : : This looks like another boring day. Of course, whenever we use placeholders like , , etc... in outputs, you will replace them by the appropriate value. Without the < and >. When he dies, he says: <NAME>: My job here is done! Our Warlock must also be able to introduce himself, while boasting with all its might. So you will write the following function: * void introduce() const; It must display: <NAME>: I am <NAME>, <TITLE>! Here's an example of a test main function and its associated output: int main() { Warlock const richard("Richard", "Mistress of Magma"); richard.introduce(); std::cout << richard.getName() << " - " << richard.getTitle() << std::endl; Warlock* jack = new Warlock("Jack", "the Long"); jack->introduce(); jack->setTitle("the Mighty"); jack->introduce(); delete jack; return (0); } ~$ ./a.out | cat -e Richard: This looks like another boring day.$ Richard: I am Richard, Mistress of Magma!$ Richard - Mistress of Magma$ Jack: This looks like another boring day.$ Jack: I am Jack, the Long!$ Jack: I am Jack, the Mighty!$ Jack: My job here is done!$ Richard: My job here is done!$ ~$ chevron-rightWarlock.hpp[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-05/module-0#warlock.hpp) chevron-rightWarlock.cpp[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-05/module-0#warlock.cpp) [PreviousExam Rank 05chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-05) [NextTeamchevron-right](https://42-cursus.gitbook.io/guide/team) Last updated 1 year ago sun-brightdesktopmoon Copy #pragma once #include <iostream> class Warlock { private: std::string name; std::string title; Warlock(); Warlock(Warlock const &other); Warlock &operator=(Warlock const &other); public: Warlock(std::string const &name, std::string const &title); ~Warlock(); std::string const &getName() const; std::string const &getTitle() const; void setTitle(std::string const &title); void introduce() const; }; Copy #include "Warlock.hpp" Warlock::Warlock(std::string const &name, std::string const &title) { this->name = name; this->title = title; std::cout << this->name << ": This looks like another boring day.\n"; } Warlock::~Warlock() {std::cout << this->name << ": My job here is done!\n";} std::string const &Warlock::getName() const { return (this->name);} std::string const &Warlock::getTitle() const { return (this->title);} void Warlock::setTitle(std::string const &title) { this->title = title;} void Warlock::introduce() const { std::cout << this->name << ": I am " << this->name << ", " << this->title << "!\n";} sun-brightdesktopmoon --- # ft_strncmp | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#subject) Subject Copy STRNCMP(3) (simplified) NAME strncmp -- compare strings SYNOPSIS int strncmp(const char *s1, const char *s2, size_t n); DESCRIPTION The strncmp() function lexicographically compare the null-terminated strings s1 and s2. The strncmp() function compares not more than n characters. Because strncmp() is designed for comparing strings rather than binary data, characters that appear after a '\0' character are not compared. RETURN VALUES The strncmp() function returns an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned characters, so that '\200' is greater than '\0'. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#understandable-explanation) Understandable explanation `strncmp()` compares string in a lexicographic order, this means that it compares each characters by their corresponding ASCII values. `strncmp()` compares maximum `n` characters in both strings. The returned value depends on what difference is found. If the two strings are the same, the returned result will be `0` since there is no difference. If there is a difference, and the first different character in `s2` is greater than the character at the same place in `s1`, the returned result will be negative. If there is a difference, and the first different character in `s2` is less than the character at the same place in `s1`, the returned result will be positive. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#commented-solution) Commented solution chevron-rightft\_strncmp[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#ft_strncmp) [Previousft\_strrchrchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr) [Nextft\_memchrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp#commented-solution) sun-brightdesktopmoon ft\_strncmp.c Copy int ft_strncmp(const char *s1, const char *s2, size_t n) { /* loop over both string until we reach n characters */ /* check if current s1 character is different than * current s2 character */ /* if characters are different, return the difference * between both characters */ /* if we read both strings until n characters and no difference * were found, return 0 as there is no difference */ } ft\_strncmp.c Copy #include "libft.h" int ft_strncmp(const char *s1, const char *s2, size_t n) { size_t i; i = 0; while ((s1[i] || s2[i]) && i < n) { if ((unsigned char) s1[i] != (unsigned char) s2[i]) return ((unsigned char) s1[i] - (unsigned char) s2[i]); i++; } return (0); } sun-brightdesktopmoon --- # CPP00 | Guide This CPP module is here to make you learn the basics of C++ and the main principles of this programming language. I'll do my best to guide you through every topics that is mentioned in this module. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#main-topics) Main topics Let's go over the main topics that are present on the first page of the subject : Copy Namespaces, classes, member functions, stdio streams, initialization lists, static, const, and some other basic stuff ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#namespaces) Namespaces A namespace is a way to scope a variable / method or anything else in your code. Let's take a look at a simple example using a namespace in two different ways. Copy #include <iostream> using namespace std; // this line sets the namespace to std // this means that we don't have to write std:: before // using any of the functions / variables in the iostream header // this code is an example of using a namespace globally int main(void) { cout << "Hello World!" << endl; return (0); } Those are two simple cases, to show you the difference between using a namespace globally and not using a namespace. In this case, that is not very interesting but take a look at the following code. circle-exclamation Note that the above code will not compile, but it gives you an idea. You can have multiple functions having the same name, then you can specify a namespace to call the correct function. Go search some the internet for more information and try to build small C++ projects to understand how it works precisely. Source: [https://learn.microsoft.com/en-us/cpp/cpp/namespaces-cpp?view=msvc-170arrow-up-right](https://learn.microsoft.com/en-us/cpp/cpp/namespaces-cpp?view=msvc-170) ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#constructor-functions-and-initialization-lists) Constructor functions & initialization lists A constructor function is a special method inside a class that is automatically called whenever you create a new object of the class. A simple constructor could be implemented like this: circle-exclamation A constructor always has the same name as the class itself and does not return anything. Let's take another example. In the main function, both car will be created as car objects, but one of them will directly have all the properties set to correct values, the other one will have default values. Since the constructor functions are called when you create a new object of a specific class, you could specify some default values to be set directly in the constructor so you're sure they are correct when you try to use them. These are constructors that I used in one of the modules: Why is there a semi-colon and properties name after the constructor parameters ? Well, there another term that is related to constructor functions : `initialization lists`. These are initialization lists, what it does is set the class attribute based on the value between the parentheses. This line is equivalent to the following code. It's an easier and better way to assign values inside the constructor function. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#classes) Classes If you didn't read the **w3schools** C++ introduction guide linked above, go ahead and read it, there's a lot of detailed information about classes since it's a central part of C++ and OOP. Here I'll give you the file structure of this module. 42 Norm and C++ good practices will make you have something looking like this for every C++ project you'll build. What you'll have at the end of projects using classes, is an `hpp` file containing the class definition, and a corresponding `cpp` file containing the class declaration. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#member-functions) Member functions Member functions are operators or functions declared as members of a class. In the code example for the [Namespaces](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#namespaces) , both `print` functions are member functions. You could have more than that, take a look at the following class declaration (it might be a bit scary now, but it's actually pretty simple): In this example, you can see that there are 9 member functions, 4 constructor functions, 1 destructor function and 1 operator member. [PreviousCPP (00 - 04) (doing)chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing) [NextCPP01chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01) Last updated 2 years ago * [Main topics](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#main-topics) * [Namespaces](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#namespaces) * [Constructor functions & initialization lists](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#constructor-functions-and-initialization-lists) * [Classes](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#classes) * [Member functions](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00#member-functions) sun-brightdesktopmoon Copy #include <iostream> // notice that this time we don't add the // using namespace std; // line // this code does exactly the same thing as the one above int main(void) { std::cout << "Hello World!" << std::endl; return (0); } Copy #include <iostream> class FirstClass: { public: FirstClass(); ~FirstClass(); void print(std::string txt); }; class SecondClass: { public: SecondClass(); ~SecondClass(); void print(void); }; int main(void) { // now if you want to call the print function, you'll have to specify a namespace // the namespace will correspond to the class of the print function // you want to call // for example, to call the print(void) function, you'll have to write the following SecondClass::print(void); // and if you want to call the print(std::string txt) function FirstClass::print("My text"); // if you try to do the following FirstClass::print(void); // it will not work, since the function FirstClass::print(void) does not // exist in the FirstClass namespace // the same goes for this SecondClass::print("Text"); // for the same reason return (0); } Copy class Class { // The class public: // Access specifier Class() { // Constructor std::cout << "Hello World!"; } }; int main() { Class Obj; // Create an object of Class, this will automatically call the constructor return 0; } Copy class Car { public: Car(); // Constructor declaration Car(std::string pbrand, std::string pmodel, int pyear); // second constructor std::string brand; std::string model; int year; }; Car::Car(void) { std::cout << "Hello world !" << std::endl; brand = ""; model = ""; year= 0; return ; } Car::Car(std::string pbrand, std::string pmodel, int pyear) { brand = pbrand; model = pmodel; year = pyear; return ; } int main() { // Create Car objects and call the constructor with different values Car car1(); Car car2("Ford", "Mustang", 1969); // Print values std::cout << car1.brand << " " << car1.model << " " << car1.year << std::endl; std::cout << car2.brand << " " << car2.model << " " << car2.year << std::endl; return 0; } Copy // Default constructor, everything is set by the callee ClapTrap::ClapTrap(void) : _name("Default"), _hp(10), _ep(10), _ad(0) { std::cout << "Default ClapTrap constructor called for "; std::cout << _GREEN << this->_name; std::cout << _RESET << std::endl; return ; } // Named constructor, other values are set by the callee ClapTrap::ClapTrap(std::string name) : _name(name), _hp(10), _ep(10), _ad(0) { std::cout << "Named ClapTrap constructor called for "; std::cout << _GREEN << this->_name; std::cout << _RESET << std::endl; return ; } // Full constructor, everything is set by the caller ClapTrap::ClapTrap(std::string name, uint hp, uint ep, uint ad) : _name(name), _hp(hp), _ep(ep), _ad(ad) { std::cout << "Full ClapTrap Constructor called for "; std::cout << _GREEN << this->_name << _RESET; std::cout << " with " << _YELLOW << this->_hp << _RESET << " hp, "; std::cout << _YELLOW << this->_ep << _RESET << " ep, " << _YELLOW << this->_ad << _RESET << " ad."; std::cout << std::endl; return ; } Copy ClapTrap::ClapTrap(std::string name, uint hp, uint ep, uint ad) : _name(name), _hp(hp), _ep(ep), _ad(ad) Copy ClapTrap::ClapTrap(std::string name, uint hp, uint ep, uint ad) { _name = name; _hp = hp; _ep = ep; _ad = ad; } Copy cpp00/ ├─ ex00/ │ ├─ ... ├─ ex01/ │ ├─ Makefile │ ├─ main.cpp │ ├─ PhoneBook.cpp │ ├─ PhoneBook.hpp │ ├─ Contact.cpp │ ├─ Contact.hpp Copy class Bureaucrat { public: Bureaucrat(void); Bureaucrat(std::string name); Bureaucrat(std::string name, int grade); Bureaucrat(const Bureaucrat &b); ~Bureaucrat(); Bureaucrat &operator=(const Bureaucrat &b); void setName(std::string name); void setGrade(int grade); std::string getName(void) const; int getGrade(void) const; void incrementGrade(void); void decrementGrade(void); void signForm(AForm &f); void executeForm(AForm &f); private: std::string _name; int _grade; }; sun-brightdesktopmoon --- # Functions used | Guide You are allowed to use several functions in this project. You already know some of them like `write`, `ft_printf`, `malloc`, `free` and all the functions from your `libft`. However, other important functions that have never been used before will be **essential** to the success of this project. Let's look at them together. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#access) access() Copy int access(const char *pathname, int mode); `access()` checks whether the program can access the file `pathname`. The `mode` specifies the accessibility check(s) to be performed, and is either the value `F_OK`, or a mask consisting of the bitwise OR of one or more of `R_OK`, `W_OK`, and `X_OK`. `F_OK` tests for the existence of the file. `R_OK`, `W_OK`, and `X_OK` test whether the file exists and grants read, write, and execute permissions, respectively. On success (all requested permissions granted), zero is returned. On error (at least one bit in `mode` asked for a permission that is denied, or some other error occurred), -1 is returned, and `errno` is set appropriately. chevron-rightaccess() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#access-example) Copy #include <unistd.h> #include <stdio.h> int main() { if (access("readfile", R_OK) == 0) printf("readfile is accessible in reading mode\n"); if (access("writefile", W_OK) == 0) printf("writefile is accessible in writing mode\n"); if (access("executefile", X_OK) == 0) printf("executefile is accessible in execution mode\n"); if (access("rwfile", R_OK|W_OK) == 0) printf("rwfile is accessible in writing and reading mode\n"); } In this example, we use the `access` function multiple times. The first time we check whether the program can read `readfile` or not. The second time we check whether the program can write in `writefile` or not. The third time we check whether the program can execute `executefile` or not. The fourth time is an example using the bitwise `OR` operator to check whether the file `rwfile` is accessible in read `AND` write mode or not. You can find more information on `access()` here: [https://linux.die.net/man/2/accessarrow-up-right](https://linux.die.net/man/2/access) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#dup2) dup2() Copy int dup2(int oldfd, int newfd); `dup2()` makes `newfd` be the copy of `oldfd`, closing `newfd` first if necessary, but note the following: * If `oldfd` is not a valid file descriptor, then the call fails, and `newfd` is not closed. * If `oldfd` is a valid file descriptor, and `newfd` has the same value as `oldfd`, then `dup2()` does nothing, and returns `newfd`. After a successful return from `dup2()`, the old and new file descriptor may be used interchangeably. They refer to the same open file description and thus share file offset and file status flags; for example, if the file offset is modified by using `lseek()` on one of the descriptors, the offset is also changed for the other. On error, the `dup2()` function returns `-1`. chevron-rightdup2() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#dup2-example) In this example, first we open both `in` and `out` file, in reading and writing mode respectively. Then we use `dup2()` to replace the `stdin` file descriptor by the `in` file descriptor. This way, whatever the command that comes after will read from the `stdin` will be whatever the content of `in` is since the `stdin` file descriptor now "points" to the `in` file. Then, we can close `in` and `out`, we don't use them anymore, right ? We set the `stdin` file descriptor to be the same as `in`, so now we only use `stdin`, `in` and `out` are not used anymore, we can close them. Now, we use the `execve()` function to execute the `grep` shell command (this is explained below on this page). When `grep` is launched without any argument, it reads text from the standard input before executing. What will happen then ? Remember we replaced the `stdin` file descriptor by `in`, so `grep` will read from the standard input, the standard input now reads from the `in` file, so `grep` will execute on whatever the content of the `in` file is. You can find more information on `dup2()` here: [https://linux.die.net/man/2/dup2arrow-up-right](https://linux.die.net/man/2/dup2) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#pipe) pipe() `pipe()` creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array `pipefd` is used to return two file descriptors referring to the ends of the pipe. `pipefd[0]` refers to the read end of the pipe. `pipefd[1]` refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe On success, `0` is returned. On error, `-1` is returned, and `errno` is set appropriately. chevron-rightpipe() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#pipe-example) Read the comments to check what is happening, it's pretty hard to explain in an other way, I'll add schema when I will be finished with the project. In this example we create a pipe, and replace the standard input with the input part of the pipe for our child process. For the parent process, we replace the standard output with the output part of the pipe. At the very end, we use the `waitpid()` function to wait for the child process to finish before making the prompt reappear. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#fork) fork() `fork()` creates a new process by duplicating the calling process. The new process, referred to as the `child`, is an exact duplicate of the calling process, referred to as the `parent`, except for some points that you can find [herearrow-up-right](https://linux.die.net/man/2/fork) (there's too may to write them all down here). chevron-rightfork() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#fork-example) I used the same example as the pipe function because it goes with it (at leas for this project), each command you want to execute takes its own child process, so you have to fork your parent into as many child processes as commands you have to execute. ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#waitpid) waitpid() The `waitpid()` system call suspends execution of the calling process until a child specified by _pid_ argument has changed state. By default, `waitpid()` waits only for terminated children. chevron-rightwaitpid() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#waitpid-example) In this example, we create a child process by forking the main process. We save the pid of the child in the `pid` variable and we wait for it at the end. You can find more information about `wait()` and `waitpid()` [herearrow-up-right](https://linux.die.net/man/2/wait) . ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#wait) wait() The `wait()` system call suspends execution of the calling process until one of its children terminates. chevron-rightwait() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#wait-example) In the first main function, we wait for one child process to terminate before going further. In the second main function, we wait for children one at a time, each time one terminates, we remove `1` from `n` until it reaches `0` and then continue. You can find more information about `wait()` and `waitpid()` [herearrow-up-right](https://linux.die.net/man/2/wait) . ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#execve) execve() `execve()` executes the program pointed to by `filename`. execve() does not return on succes, the calling process is **replaced** by the executed `filename`. chevron-rightexecve() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#execve-example) ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#unlink) unlink() `unlink()` deletes a name from the file system. If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available for reuse. If the name was the last link to a file but any processes still have the file open the file will remain in existence until the last file descriptor referring to it is closed. On success, `0` is returned. On error, `-1` is returned, and `errno` is set appropriately. chevron-rightunlink() example[hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#unlink-example) In this example, we use the `access()` function to check if the file called `tmp` exists, if its the case, we use the `unlink()` function to remove it. You can find more information about `unlink()` [herearrow-up-right](https://linux.die.net/man/2/unlink) . ### [hashtag](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#final-word) Final word The way pipes are described generally is that it redirects the output of one command to the input of the next command. That is correct. But there's a catch, when you build pipex, you have to launch a new child process for each command you want to do, and they are all made at the same time. That means all commands are run at the same time, it's just that they will wait for the writing end of the pipe to be closed before reading from the pipe. [PreviousUnderstand pipexchevron-left](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/understand-pipex) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/building-the-thing) Last updated 1 year ago * [access()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#access) * [dup2()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#dup2) * [pipe()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#pipe) * [fork()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#fork) * [waitpid()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#waitpid) * [wait()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#wait) * [execve()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#execve) * [unlink()](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#unlink) * [Final word](https://42-cursus.gitbook.io/guide/2-rank-02/pipex/functions-used#final-word) sun-brightdesktopmoon Copy #include <unistd.h> #include <fcntl.h> int main(int ac, char *av[], char *env[]) { (void) ac; (void) av; int in; int out; char *grep_args[] = {"grep", "Lausanne", NULL}; // open input and output files (assuming both files exist) in = open("in", O_RDONLY); out = open("out", O_WRONLY); // replace standard input with input file dup2(in, 0); // close unused file descriptors close(in); close(out); // execute grep execve("grep", grep_args, env); } Copy int pipe(int pipefd[2]); Copy /** * Executes the command "cat infile | grep Lausanne". */ #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int ac, char *av[], char *env[]) { (void) ac; (void) av; int pipefd[2]; int pid; char *cat_args[] = {"/bin/cat", "infile", NULL}; char *grep_args[] = {"/usr/bin/grep", "Lausanne", NULL}; // make a pipe // fds go in pipefd[0] and pipefd[1] pipe(pipefd); if (pid == 0) { // child process gets here and handles "grep Lausanne" // replace standard input with input part of the pipe dup2(pipefd[0], 0); // close unused half of the pipe close(pipefd[1]); // execute grep execve("/usr/bin/grep", grep_args, env); } else { // parent process gets here and handles "cat scores" // replace standard output with output part of pipe dup2(pipefd[1], 1); // close unused half of the pipe close(pipefd[0]); // execute cat execve("/bin/cat", cat_args, env); } // close unused pipe close(pipefd[0]); close(pipefd[1]); // wait for the child process to finish waitpid(pid); } Copy pid_t fork(void); Copy /** * Executes the command "cat infile | grep Lausanne". */ #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int ac, char *av[], char *env[]) { (void) ac; (void) av; int pipefd[2]; int pid; char *cat_args[] = {"/bin/cat", "infile", NULL}; char *grep_args[] = {"/usr/bin/grep", "Lausanne", NULL}; // make a pipe // fds go in pipefd[0] and pipefd[1] pipe(pipefd); if (pid == 0) { // child process gets here and handles "grep Lausanne" // replace standard input with input part of the pipe dup2(pipefd[0], 0); // close unused half of the pipe close(pipefd[1]); // execute grep execve("/usr/bin/grep", grep_args, env); } else { // parent process gets here and handles "cat scores" // replace standard output with output part of pipe dup2(pipefd[1], 1); // close unused half of the pipe close(pipefd[0]); // execute cat execve("/bin/cat", cat_args, env); } // close unused pipe close(pipefd[0]); close(pipefd[1]); // wait for the child process to finish waitpid(pid); } Copy pid_t waitpid(pid_t pid, int *status, int options); Copy #include <sys/types.h> #include <sys/wait.h> int main(void) { int pid; pid = fork(); waitpid(pid); } Copy pid_t wait(int *status); Copy #include <sys/types.h> #include <sys/wait.h> // waiting for one child int main(void) { int status; wait(&status); } // waiting for multiple children int main(void) { int status; while (n > 0) { wait(&status); n--; } } Copy int execve(const char *filename, char *const argv[], char *const envp[]); Copy #include <unistd.h> int main(int ac, char **av, char **envp) { (void) ac; const char *filename = "/usr/bin/grep"; char *const argv[] = {"/usr/bin/grep", "a", NULL}; execve(filename, argv, envp); } Copy int unlink(const char *pathname); Copy #include <unistd.h> int main(void) { if (access("tmp", F_OK) == 0) unlink("tmp"); return (0); } sun-brightdesktopmoon --- # ft_memcmp | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#subject) Subject Copy MEMCMP(3) (simplified) NAME memcmp -- compare byte string SYNOPSIS int memcmp(const void *s1, const void *s2, size_t n) DESCRIPTION The memcmp() function compares byte string s1 against byte string s2. Both strings are assumed to be n bytes long. RETURN VALUES The memcmp() function returns zero if the two strings are identical, otherwise returns the difference betwee the first two differing bytes (treated as unsigned char values, so that '\200' is greater than '\0', for example). Zero-length strings are always identical. This behaviour is not required by C and portable code should only depend on the sign of the returned value. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#understandable-explanation) Understandable explanation `memcmp()` compares byte strings. It works similarly to the `strncmp()` function. The difference here is that `memcmp()` works with bytes strings so it take void pointers as parameter, plus a third character, representing, as said in the man, the assumed length of both strings. This means that `memcmp()` will not compare more than `n` bytes. The return value depends on what difference is found. If there is no difference between both strings, the return value will be 0. If there is a difference, and the first different character in `s2` is greater than the character at the same place in `s1`, the returned result will be negative. If there is a difference, and the first different character in `s2` is less than the character at the same place in `s1`, the returned result will be positive. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#hints) Hints [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#commented-solution) Commented solution --------------------------------------------------------------------------------------------------------------------------------- chevron-rightft\_memcmp[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#ft_memcmp) [Previousft\_memchrchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr) [Nextft\_strnstrchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp#commented-solution) sun-brightdesktopmoon ft\_memcmp.c Copy int ft_memcmp(const void *s1, const void *s2, size_t n) { /* loop over both strings until we reach n bytes */ /* check if current s1 byte is different than current * s2 byte */ /* if bytes are different, return the difference * between both characters */ /* if we read both byte strings until n bytes and no difference * were found, return 0 as there is no difference */h2 } ft\_memcmp.c Copy #include "libft.h" int ft_memcmp(const void *s1, const void *s2, size_t n) { unsigned char *str1; unsigned char *str2; size_t i; /* converting s1 and s2 to unsigned char */ str1 = (unsigned char) *s1; str2 = (unsigned char) *s2; i = 0; /* same loop as strcmp */ while (i < n) { /* check if current byte is different in both strings */ if ((unsigned char) str1[i] != (unsigned char) str2[i]) /* return the difference between both chars */ return ((unsigned char) str1[i] - (unsigned char) str2[i]); } /* if we read through both strings completely and there * were no difference, we return 0 */ return (0); } sun-brightdesktopmoon --- # ft_strrchr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#subject) Subject Copy STRRCHR(3) (simplified) NAME strrchr -- locate character in string SYNOPSIS char *strrchr(const char *s, int c); DESCRIPTION The strrchr() function is identical to strchr(), except it locates the last occurence of c. RETURN VALUES The function strrchr() returns a pointer to the located character, or NULL if the character does not appear in the string. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#understandable-explanation) Understandable explanation This function is fairly easy to understand, it does the same thing as `strchr()`, but locates the last occurence of c. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#hints) Hints ft\_strrchr.c Copy char *ft_strrchr(const char *s, int c) { /* we can use basically the same code as ft_strchr() but not returning * the value as soon as we find the character, just setting a variable * each time, and returning it at the end of the function */ /* loop over the whole string */ /* check if current character is equal to the one we have to find */ /* once we looped over the whole string, check again for the character * in case the character we have to find is '\0' */ /* if we didn't find c in the string, return NULL */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#commented-solution) Commented solution chevron-rightft\_strrchr[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#ft_strrchr) [Previousft\_strchrchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strchr) [Nextft\_strncmpchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strrchr#commented-solution) sun-brightdesktopmoon ft\_strrchr.c Copy #include "libft.h" char *ft_strrchr(const char *s, int c) { unsigned int i; char *res; char cc; /* we convert c to a char as we got it as an int */ cc = (char) c; /* we set res as NULL at the beginning so if we don't find * any occurence of c, the function will return NULL */ res = NULL; i = 0; /* looping over the whole string s */ while (s[i]) { /* if the current character is equal to cc * this means we found an occurence of cc in the string * therefore, we set res as the address of the character */ if (s[i] == cc) res = (char *) &s[i]; /* we then advance in the string to search for another * occurence of cc */ i++; } /* once we looped over the whole string, if we didn't find an * occurence of cc, we have to check if cc is equal to '\0' * so we check once again if the current character is equal to cc * if this is the case, we set res as the address of the '\0' char */ if (s[i] == c) res = (char *) &s[i]; /* when we reach the end of the function, we return res * since we looped over the whole string and set res as the address * of the last occurence of c we found, this will return a pointer * to the last occurence of c * and if we didn't find any occurence of c, since res was set to * NULL at the very beginning of the function, the function will * return NULL */ return (res); } sun-brightdesktopmoon --- # ft_calloc | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#subject) Subject Copy CALLOC(3) (simplified) NAME calloc -- memory allocation SYNOPSIS void *calloc(size_t count, size_t size); DESCRIPTION The calloc() function allocates memory. The allocated memory is aligned such that it can be used for any data type. The calloc() function contigously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero. RETURN VALUES If successful, calloc() returns a pointer to allocated memory. If there is an error, they return a NULL pointer and set errno to ENOMEM. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#understandable-explanation) Understandable explanation By now you should have understand what the `malloc()` function does, at least I hope. Otherwise, understand how `malloc()` works and come back here. I will mainly base my explanation on comparing `calloc()` to `malloc()`. `calloc()` works in the same way as `malloc()` does, but the difference is that `calloc()` sets all the memory bytes are set to `0` instead of staying as the gibberish that was there in memory before we allocated it. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#commented-solution) Commented solution chevron-rightft\_calloc[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#ft_calloc) [Previousft\_atoichevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi) [Nextft\_strdupchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc#commented-solution) sun-brightdesktopmoon ft\_calloc.c Copy void *ft_calloc(size_t count, size_t size) { /* declare a tmp unsigned char pointer */ /* use malloc to allocate count * size in tmp */ /* loop over tmp and set each byte to 0 */ /* return tmp */ } ft\_calloc.c Copy #include "libft.h" void *ft_calloc(size_t count, size_t size) { unsigned char *tmp; size_t i; i = 0; /* allocating count * size bytes in memory with malloc */ tmp = malloc(count * size); /* check if the memory was allocated */ if (!tmp) return (NULL); /* loop over every allocated bytes and set it to 0 */ while (i < count * size) tmp[i++] = 0; /* return the allocated memory */ return (tmp); } sun-brightdesktopmoon --- # ft_strnstr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#subject) Subject Copy STRNSTR(3) (simplified) NAME strnstr -- locate a substring in a string SYNOPSIS char *strnstr(const char *haystack, const char *needle, size_t len); DESCRIPTION The strnstr() function locates the first occurence of the null-terminated string needle in the string haystack, where not more than len characters are searched. Characters that appear after a '\0' character are not searched. RETURN VALUES If needle is an empty string, haystack is returned; if needle occurs nowhere in haystack, NULL is returned; otherwise a pointer to the first character of the first occurence of needle is returned. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#understandable-explanation) Understandable explanation The `strnstr()` function works in the same way as `strchr()` but searches for a complete substring in max `n` characters instead of a single character. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#hints) Hints ft\_strnstr.c Copy char *ft_strnst(const char *haystack, const char *needle, size_t len) { /* check if needle is empty */ /* return haystack */ /* loop over haystack */ /* while current character of haystack is equal to the corresponding * character in needle */ /* check if we have the complete needle */ } I can also tell you that you'll need two different counters. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#commented-solution) Commented solution chevron-rightft\_strnstr[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#ft_strnstr) [Previousft\_memcmpchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp) [Nextft\_atoichevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr#commented-solution) sun-brightdesktopmoon ft\_strnstr.c Copy #include "libft.h" char *ft_strnstr(const char *haystack, const char *needle, size_t len) { size_t i; size_t j; i = 0; j = 0; /* checking if needle is empty */ if (needle[0] == 0) return ((char *) haystack); /* loop over haystack while we haven't looped over the whole * thing or until i = len */ while (haystack[i] && i < len) { /* inside this first while loop * we are looping over the haystack as long as * the current character is the correct character * in the needle */ while (haystack[i + j] == needle[j] && haystack[i + j] && i + j < len) { /* we are inside this loop while the current * haystack character is the correct character in the * needle so we just increment j to offset our haystack */ j++; /* if needle[j] == 0, this means we read the whole * needle, so we found it in the haystack * we can return a pointer to the first character of * the needle * that why we used 2 counters, now we can offset our * haystack pointer by i, which is the position of the * first character of the needle */ if (needle[j] == 0) return ((char *) haystack + i); } i++; /* don't forget to set j to 0 again, otherwise you will * be offsetted in the needle beginning from the second * haystack character */ j = 0; } return (0); } sun-brightdesktopmoon --- # ft_strdup | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#subject) Subject Copy STRDUP(3) (simplified) NAME strdup -- save a copy of a string SYNOPSIS char *strdup(const char *s1); DESCRIPTION The strdup() function allocates sufficient memory for a copy of the string s1, does the copy, and returns a pointer to it. The pointer may subsequently be used as an argument to the function free(3). If insufficient memory is available, NULL is returned and errno is set to ENOMEM. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#understandable-explanation) Understandable explanation For once, the man is really clear on what the function does. So I don't think I need to explain it with more details. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#hints) Hints We have to use malloc for this since the returned value of this function must be 'freeable' with the free function. ft\_strdup.c Copy char *ft_strdup(const char *s1) { /* use malloc to allocate enough space for s1 * we will have to copy it completely * so we need enough space for it */ /* loop over s1 and copy each character in the new string you * just allocated */ /* return the allocated and copied string */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#commented-solution) Commented solution chevron-rightft\_strdup[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#ft_strdup) [Previousft\_callocchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc) [NextAdditional functionschevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/additional-functions) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strdup#commented-solution) sun-brightdesktopmoon ft\_strdup.c Copy #include "libft.h" char *ft_strdup(const char *s1) { char *dest; size_t i; /* allocating enough memory for s1 + 1 character * for the NUL-terminating character */ dest = (char *) malloc(ft_strlen(s1) + 1); if (!dest) return (NULL); i = 0; /* looping over the whole s1 string */ while (s1[i]) { /* copying the current s1 character into the same * position in the dest string we allocated above */ dest[i] = s1[i]; i++; } /* setting the NUL-terminating character */ dest[i] = 0; /* finally, we return the newly created string */ return (dest); } sun-brightdesktopmoon --- # ft_memchr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#subject) Subject Copy MEMCHR(3) (simplified) NAME memchr -- locate byte in byte string SYNOPSIS void *memchr(const void *s, int c, size_t n); DESCRIPTION the memchr() function locates the first occurence of c (convered to an unsigned char) in string s. RETURN VALUES The memchr() function returns a pointer to the byte located, or NULL if no such byte exists within n bytes. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#understandable-explanation) Understandable explanation The `memchr()` function works similarly as the `strchr()` function, the difference is that `memchr()` works with byte string (`void *`) where `strchr()` works with 'litteral' strings (`char *`). This means we can send whatever type of data we want to `memchr()` and it'll still work. `memchr()` also has a third parameter, `n`. This parameter tells the function how many bytes we want to search in. We need this parameter since `s` is not a 'litteral' string, it doesn't have a NUL-terminating character. If we didn't have this parameter, we would be reading a random number of bytes each time. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#hints) Hints ft\_memchr.c Copy void *ft_memchr(const void *s, int c, size_t n) { /* as said in the man, the search is done for c converted to * an unsigned char, so we have to convert both c and s to * unsigned char */ /* loop over the byte string until our counter is equal to n */ /* compare the current byte to c */ /* if they are the same, return the address of this byte as a * void * */ /* if we searched n bytes and didn't find what we were looking for * return NULL */ /* as you can see, this is very close to the strchr and strrchr * functions, so take a look at these before looking at the * solution */ } ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#commented-solution) Commented solution chevron-rightft\_memchr.c[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#ft_memchr.c) [Previousft\_strncmpchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strncmp) [Nextft\_memcmpchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memcmp) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_memchr#commented-solution) sun-brightdesktopmoon ft\_memchr.c Copy #include "libft.h" void *ft_memchr(const void *s, int c, size_t n) { unsigned char *str; size_t i; unsigned char uc; /* converting both s and c to unsigned char */ str = (unsigned char *) s; uc (unsigned char) c; i = 0; /* looping over n bytes */ while (i < n) { /* same check as strchr */ if (str[i] == uc) /* there, we return a void pointer instead * of the char pointer we returned in strchr */ return ((void *) &str[i]); i++; } /* if we reached this point, we didn't find any occurence * of c in n bytes, so we return NULL */ return (NULL); } sun-brightdesktopmoon --- # CPP01 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#main-topics) Main topics Let's go over the main topics that are present on the first page of the subject : Copy Memory allocation, pointers to members, references, switch statement ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#memory-allocation) Memory allocation Remember that C++ basically is an extension of C, yeah so memory allocation also exists in C++. It's mainly not done in the same way as in C. In C we have `malloc` and `free`, in C++ we have `new` and `delete`. Let's take an example comparing C and C++ since you already know C memory management pretty well. C Code Copy #include <stdlib.h> #include <stdio.h> int main(void) { int *ptr; // declare the pointer ptr = malloc(sizeof(int)); // allocate the memory *ptr = 45; // assign a value printf("ptr value: %d\n", *ptr); // print the value free(ptr); // deallocate the memory return (0); } In this case, both codes are exactly the same, now let's look at how you would do that for a dynamically allocated array. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#pointers-to-members) Pointers to members First of all, what are pointers to members ? Remember that in C, we have pointers to variable and pointers to functions. These also exists in C++ but there's also 2 new pointer types in C++ to introduce the class concept into pointers. I'll put down here the code example from the intra video on pointers to members. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#operator) .\* operator > Refers to line 16 in the above example We set `Sample::*p` to point to a member `foo` in the `Sample` class. The thing is, we could have multiple instances of the `Sample` class, so we have to specify on which instance we want to use the pointer by using the following syntax: `instance.*pointerToMemberAttribute`. This is because the `foo` member attribute can exist in multiple class instances. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#greater-than-operator) \- >\* operator > Refers to line 19 in the above example Here we are not using the `Sample` instance directly anymore, we have to use the `->*` operator instead of the `.*` operator. It works exactly the same way but it adds a level of dereference in between. This syntax: `instancePtr->*pointerToMemberAttribute` where `instancePtr` points to an `instance` of the `Sample` class, does the same thing as the `.*` operator used on instance variable directly. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#call-member-function-from-pointer-to-member-function) Call member function from pointer to member function > Refers to line 24 and 25 in the above example For pointers to member functions, it works in the same way as pointer to member attributes. We first set to which member function we want the pointer to point, and when we want to call the function, we have to specify on which instance of the class we'll call the function. In the same way as pointer to member attributes, we have the two operators, `.*` and `->*`. The `.*` operator is used when we use the instance variable directly, and the `->*` is used when we have a pointer to an instance variable. ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#references) References References are a new concept, that does not exist in `C`, it's close as what the pointers do in `C`. The more accurate definition of a reference is the following: > A reference is a pointer that is constant and is always dereferenced, it can never be `void`\\ Let's take the first example from the intra video With just the definition given above, can you guess the output of the above code ? chevron-rightCode result[hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#code-result) Now, we'll take the same example, but this time, I'll comment it so that we can understand what is being done in this code. #### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#things-to-note-about-references-in-c) Things to note about references in C++ * A reference is somehow like a dereferenced pointer * Once it's defined it will always be referencing the same value * You cannot declare a reference without assigning it a value directly * References are constant, you can't change what it references after the declaration * A reference cannot be `void`, unlike a pointer that can be void Some things of the above list in the form of code, as it can be better visualize by some: ### [hashtag](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#switch-statement) Switch statement There's already something about the `switch` statement that you can read [here](https://42-cursus.gitbook.io/guide/useful-tools/switch-statement) . [PreviousCPP00chevron-left](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp00) [NextCPP02chevron-right](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp02) Last updated 2 years ago * [Main topics](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#main-topics) * [Memory allocation](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#memory-allocation) * [Pointers to members](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#pointers-to-members) * [References](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#references) * [Switch statement](https://42-cursus.gitbook.io/guide/4-rank-04/cpp-00-04-doing/cpp01#switch-statement) sun-brightdesktopmoon C++ Code Copy #include <iostream> int main(void) { int *ptr; // declare the pointer ptr = new int; // allocate memory *ptr = 45 // assign a value std::cout << "ptr value: " << *ptr << std::endl; // print the value delete ptr; // deallocate memory return (0); } C Code Copy #include <stdlib.h> int main(void) { int *ptr; ptr = malloc (10 * sizeof(int)); free(ptr); return (0); } C++ Code Copy #include <iostream> int main(void) { int *ptr; ptr = new int[10]; delete [] ptr; return (0); } Copy #include <iostream> #include <Sample.hpp> int main() { Sample instance; // instance of Sample class on the stack Sample *instancep = &instance; // pointer to the instance of Sample int Sample::*p = NULL; // pointer to member attribute of Sample class // adding the Sample:: specifies that it will point to a member attribute of the Sample class void (Sample::*f)(void) const; // pointer to member function of Sample class p = &Sample::foo; // Setting Sample::*p to be the address of the foo member attribute std::cout << "Value of member foo: " << instance.foo << std::endl; instance.*p = 21; // this line sets the value of the member attribute pointed to by *p in the instance `instance` to 21 std::cout << "Value of member foo: " << instance.foo << std::endl; instancep->*p = 42; // this line sets the value of the member attribute pointed to by *p in the instance pointed to by the `instancep` pointer std::cout << "Value of member foo: " << instance.foo << std::endl; f = &Sample::bar; (instance.*f)(); // calling the member function Bar in the instance `instance` of the Sample class (instancep->*f)(); // same thing as above, but this time with a pointer to the instance } c++ Refs UnCommented Copy #include <iostream> int main(void) { int numberOfBalls = 42; int *ballsPtr = &numberOfBalls; int &ballsRef = numberOfBalls; std::cout << numberOfBalls << " " << *ballsPtr << " " << ballsRef << std::endl; *ballsPtr = 21; std::cout << numberOfBalls << std::endl; ballsRef = 84; std::cout << numberOfBalls << std::endl; return (0); } Copy $> 42 42 42 $> 21 $> 84 c++ Refs commented Copy #include <iostream> int main(void) { int numberOfBalls = 42; // assigning 42 to the numberOfBalls variable int *ballsPtr = &numberOfBalls; // assigning the address of the numberOfBalls variable to the ballsPtr pointer int &ballsRef = numberOfBalls; // assigning ballsRef to be a reference to the numberOfBalls variable // note that for reference, we assign it directly another variable and not the adress of another variable // Now that the reference is set, we cannot change what it is referencing. // This means that I could not do this later on: ballsRef = otherIntValue; std::cout << numberOfBalls << " " << *ballsPtr << " " << ballsRef << std::endl; // The above line first prints the value of the numberOfBalls variable // it then prints the value pointed to by ballsPtr by dereferencing the pointer using the * operator // it then prints the value of ballsRef which is a reference to the numberOfBalls variable *ballsPtr = 21; // dereference the pointer to modify the value pointed to by ballsPtr std::cout << numberOfBalls << std::endl; // should print 21 ballsRef = 84; // modify the value referenced by ballsRef std::cout << numberOfBalls << std::endl; // should print 84 return (0); } Copy #include <iostream> int main(void) { int intValue = 0; int secondValue = 10; int &valRef = intValue; // Will always reference intValue int &valRef2; // this will not work as references have to be directly assigned a variable to reference valRef = secondValue; // this will not work as valRef was already set to reference intValue int &valRef3 = NULL; // this will not work, first because references cannot be void, but also because we will not be able to set it to reference something else later since they are constant } sun-brightdesktopmoon --- # Functions | Guide We can use some function that we already know (like `printf`, `malloc`, `free`, etc) so I will not describe them here. You will probably not use all of these functions but at least you have somewhere where you can easily find links to the manual pages. And for some, an example on how to use them. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#readline) readline() Copy char *readline (const char *prompt); The `readline()` function reads a line from the terminal and returns it, using `prompt` as a prompt. If no prompt is given as parameter, no prompt will be shown in the terminal. The line returned is allocated with `malloc` and we have to free it ourselves. chevron-rightreadline()[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#readline-1) Copy #include <stdio.h> #include <readline/readline.h> #include <readline/history.h> int main(void) { char *rl; rl = readline("Prompt > "); printf("%s\n", rl); return (0); } Compiling this programm and running will result in the following. Copy $> ./minishell Prompt > Hi ! How are you ? Hi ! How are you ? $> You can find more information about `readline()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/readline.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_clear_history) rl\_clear\_history() Copy void rl_clear_history(void); The `rl_clear_line()` function clears the history list by deleting all of the entries. The `rl_clear_line()` function frees data that the `readline` library saves in the histroy list. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_on_new_line) rl\_on\_new\_line() Copy int rl_on_new_line(void); The `rl_on_new_line()` function tells the update routine that we have moved onto a new empty line, usually used after outputting a line. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_replace_line) rl\_replace\_line() I didn't find any information on that function. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_redisplay) rl\_redisplay() The `rl_redisplay()` change what's displayed on the screen to reflect the current contents of `rl_line_buffer`. ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#add_history) add\_history() The `add_history()` function saves the line passed as parameter in the history so it can be retrieved later in the terminal (like pressing the up arrow in bash). ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#getcwd) getcwd() The `getcwd()` returns a null-terminated string containing the absolute pathname that is the current working directory of the calling process. The pathname is returned as the function result and via the argument `buf`. chevron-rightgetcwd() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#getcwd-example) You can find more information about `getcwd()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/getcwd.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#chdir) chdir() `chdir()` changes the current working directory of the calling process to the directory specified in `path`. chevron-rightchdir() example[hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#chdir-example) You can find more information about `chdir()` [herearrow-up-right](https://man7.org/linux/man-pages/man2/chdir.2.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#stat-and-lstat-and-fstat) stat() & lstat() & fstat() These functions return information about a file in the structure pointed to by `statbuf`. You can find more detailed information about these functions [here](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#opendir) opendir() The `opendir()` function opens a directory stream corresponding to the directory name, and returns a pointer to the directory stream. The stream is positioned at the first entry in the directory. You can find more information about the `opendir` function [herearrow-up-right](https://man7.org/linux/man-pages/man3/opendir.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#readdir) readdir() The `readdir()` function returns a pointer to a `dirent` structure representing the next directory entry in the directory stream pointed to by `dirp`. It returns `NULL` on reaching the end of the directory stream or if an error occured. You can find more information about `readdir` [herearrow-up-right](https://man7.org/linux/man-pages/man3/readdir.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#closedir) closedir() The `closedir()` function closes the directory stream associated with `dirp`. A successful call to `closedir()` also closes the underlying file descriptor associated with `dirp`. The directory stream descriptor `dirp` is not available after this call. You can find more information about `closedir` [herearrow-up-right](https://man7.org/linux/man-pages/man3/closedir.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#strerror) strerror() The `strerror()` function returns a pointer to a string that describes the error code passed in the argument errnum. This string must not be modified by the application, but may be modified by a subsequent call to `strerror()` or `strerror_l()`. No other library function, including `perror()`, will modify this string. You can find more information about `strerror` [herearrow-up-right](https://man7.org/linux/man-pages/man3/strerror.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#perror) perror() The `perror()` function produces a message on standard error describing the last error encountered during a call to a system or library function. You can find more information about `perror` [here](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#isatty) isatty() The `isatty` function tests wether `fd` is a terminal. You can find more information about `isatty` [herearrow-up-right](https://man7.org/linux/man-pages/man3/isatty.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ttyname) ttyname() The `ttyname()` function returns a pointer to the null-terminated pathname of the terminal device that is open on the file descriptor `fd`, or `NULL` on error. You can find more information about `ttyname()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/ttyname.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ttyslot) ttyslot() This is a legacy function with some backstory, you can read all about it and how it works [herearrow-up-right](https://man7.org/linux/man-pages/man3/ttyslot.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ioctl) ioctl() The `ioctl()` system call manipulates the underlying device parameters of a special files. You can find more detailed information [herearrow-up-right](https://man7.org/linux/man-pages/man2/ioctl.2.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#getenv) getenv() The `getenv()` function searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string. You can find more information about `getenv()` [herearrow-up-right](https://man7.org/linux/man-pages/man3/getenv.3.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tcsetattr) tcsetattr() The `tcsetattr()` function shall set the parameters associated with the terminal referred to by the open file descriptor `fildes` from the `termios` structure referenced by `termios_p` as described [herearrow-up-right](https://man7.org/linux/man-pages/man3/tcsetattr.3p.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tcgetattr) tcgetattr() The `tcgetattr()` function shall get the parameters associated with with the terminal reffered to by `fildes` and store them in the `termios` structure referenced by `termios_p`. You can find more detailed information [herearrow-up-right](https://man7.org/linux/man-pages/man3/tcgetattr.3p.html) . ### [hashtag](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tgetent) tgetent() These routines are included as a conversion aid for programs that use the `termcap` library. You can find more information about all of them [herearrow-up-right](https://linux.die.net/man/3/tgetent) . [PreviousUnderstand Minishellchevron-left](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/understand-minishell) [NextBuilding the thingchevron-right](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/building-the-thing) Last updated 1 year ago * [readline()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#readline) * [rl\_clear\_history()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_clear_history) * [rl\_on\_new\_line()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_on_new_line) * [rl\_replace\_line()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_replace_line) * [rl\_redisplay()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#rl_redisplay) * [add\_history()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#add_history) * [getcwd()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#getcwd) * [chdir()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#chdir) * [stat() & lstat() & fstat()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#stat-and-lstat-and-fstat) * [opendir()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#opendir) * [readdir()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#readdir) * [closedir()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#closedir) * [strerror()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#strerror) * [perror()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#perror) * [isatty()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#isatty) * [ttyname()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ttyname) * [ttyslot()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ttyslot) * [ioctl()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#ioctl) * [getenv()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#getenv) * [tcsetattr()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tcsetattr) * [tcgetattr()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tcgetattr) * [tgetent()](https://42-cursus.gitbook.io/guide/3-rank-03/minishell/functions#tgetent) sun-brightdesktopmoon Copy int rl_redisplay(void); Copy void add_history(char *s); Copy #include <unistd.h> char *getcwd(char *buf, size_t size); Copy #include <unistd.h> #include <stdio.h> // for printf int main(void) { char *pwd; pwd = getcwd(NULL, 0); printf("pwd: %s\n", pwd); return (0); } Copy $> pwd: /Users/saeby/Documents/tmp Copy #include <unistd.h> int chdir(const char *path); Copy #include <unistd.h> #include <stdio.h> // for printf int main(void) { char *pwd; pwd = getcwd(NULL, 0); printf("pwd before chdir: %s\n", pwd); chdir("/Users/saeby/Documents/42/minishell"); pwd = getcwd(NULL, 0); printf("pwd after chdir: %s\n", pwd); return (0); } Copy $> pwd before chdir: /Users/saeby/Documents/tmp $> pwd after chdir: /Users/saeby/Documents/42/minishell Copy #include <sys/stat.h> int stat(const char *restrict pathname, struct stat *restrict statbuf); int lstat(const char *restrict pathname, struct stat *restrict statbuf); int fstat(int fd, struct stat *statbuf); Copy #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); Copy #include <dirent.h> struct dirent *readdir(DIR *dirp); Copy #include <sys/types.h> #include <dirent.h> int closedir(DIR *dirp); Copy #include <string.h> char *strerror(int errnum); Copy #include <stdio.h> void perror(const char *s); Copy #include <unistd.h> int isatty(int fd); Copy #include <unistd.h> char **ttyname(int fd); Copy #include <unistd.h> int ttyslot(void); Copy #include <sys/ioctl.h> int ioctl(int fd, unsigned long request, ...); Copy #include <stdlib.h> char *getenv(const char *name); Copy #include <termios.h> int tcsetattr(int fildes, int optional_actions, const struct *termios_p); Copy #include <termios.h> int tcgetattr(int fildes, struct termios *termios_p); Copy #include <curses.h> #include <term.h> int tgetent(char *bp, const char *name); int tgetflag(char *id); int tgetnum(char *id); char *tgetstr(char *id, char **area); char *tgoto(const char *cap, int col, int row); int tputs(const char *str, int affcnt, int (*putc)(int)); sun-brightdesktopmoon --- # ft_atoi | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#subject) Subject Copy ATOI(3) (simplified) NAME atoi -- convert ASCII string to integer SYNOPSIS int atoi(const char *str); DESCRIPTION The atoi() function converts the initial portion of the string pointed to by str to int representation. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#understandable-explanation) Understandable explanation The `atoi()` function converts a string to its `int` representation. Some things that the `atoi()` function does are not clearly said in the man. I'll quickly list them here. * The string passed as parameter may begin with an arbitrary number of whitespaces as determined by `isspace(3)` * After the arbitrary number of whitespaces, there can be one single optional '+' or '-' sign * The remainder of the string will be converted to an int, stopping at the first character which is not a valid digit in the given base (in our case we only need to manage base 10, so the valid digits are 0-9) I talked about the `isspace(3)` function, what is that function ? It works the same way as the `isdigit`, `isalpha`, etc. but returning a non-zero value when the character is one of the following chevron-rightisspace(3)[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#isspace-3) * \\t => tabulation * \\n => new line * \\v => vertical tabulation * \\f => form feed * \\r => carriage return * ' ' => space To make it easier, will be coding the `isspace(3)` function as a static helper function for our `atoi(3)` function. ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#hints) Hints ### [hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#commented-solution) Commented solution chevron-rightft\_atoi[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#ft_atoi) chevron-rightConversion example[hashtag](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#conversion-example) I hope this will help you understand what happens in the while loop of our `ft_atoi()` function. [Previousft\_strnstrchevron-left](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_strnstr) [Nextft\_callocchevron-right](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_calloc) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#subject) * [Understandable explanation](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#understandable-explanation) * [Hints](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#hints) * [Commented solution](https://42-cursus.gitbook.io/guide/0-rank-00/libft/libc-functions/ft_atoi#commented-solution) sun-brightdesktopmoon ft\_atoi.c Copy int ft_atoi(const char *str) { while (/* character isspace */) /* advance in the string */ if (/* character is + and next character is not - */) /* advance in the string */ if (/* character is - */) /* save the sign as negative */ while (/* there is something in the string and that is a digit 0-9 */) /* convert the current digit value to int value */ /* don't overwrite what we already converted */ /* multiply the int result by the sign */ return (/* result */); } static int ft_isspace(int c) { if (/* c is one of the whitespace characters */) return (/* non-zero value of your choice */); return (0); } ft\_atoi.c Copy #include "libft.h" int ft_atoi(const char *str) { int result; int sign; int i; result = 0; sign = 1; i = 0; /* here we use our version of the isspace function to check if * the current character is a whitespace */ while (ft_isspace(str[i])) i++; /* checking if the character is a + character and that the next * one is not a - * we don't have to check if the following character is another + * because if the following is also a + it won't enter the following * condition that checks for a - character * and if it doesn't enter the following condition it will not enter * the main while loop that only checks for digits 0-9 */ if (str[i] == '+' && str[i + 1] != '-') i++; /* if the current character is -, we make sign equal to -1 so * we can simply multiply the final result by this sign * to get the negative or positive number */ if (str[i] == '-') { sign = -1; i++; } /* while we are not at the end of the string and the character is * a digit between 0 and 9 * we multiply the current result by 10 so we add another digit * to the result * then we add the decimal value of the current character - 48 to * the result. the -48 part comes from the ASCII table. The '0' * character as the decimal value 48, and we don't want to add 48 to * our int result, but 0, so we substract 48. * Since all digits between 0 and 9 follow each other in the ASCII * table, this substract works for every one of them. * Then we move to the next character in the string */ while (str[i] && str[i] >= 48 && str[i] <= 57) { /* take a look under this expandable, I made a clearer example * of how this part works */ result *= 10; result += str[i] - 48; i++; } /* When we converted every digit to int, we multiply the end result * by the sign variable * if the number is negative, this means we'll be multiplying by -1 * therefore getting the negative value of result * if the number is positive, since the sign variable was set to 1 at * the beginning of the function, we multiply the end result by one, * so the result value stays unchanged */ result *= sign; return (result); } int ft_isspace(int c) { /* this checks if the character is one of the whitespaces */ if (c == 9 || c == 10 || c == 11 || c == 12 || c == 13 || c == 32) /* we could return c here, if we reach this point the value of * c will be a non-zero value */ return (1); return (0); } Copy int main(void) { int result; result = 0; // result = 0 result *= 10; // result = 0 result += '1' - 48; // result = 1 result *= 10; // result = 10 result += '5' - 48; // result = 15 result *= 10; // result = 150 result += '4' - 48; // result = 154 } sun-brightdesktopmoon --- # Level 1 | Guide Here are the 12 exercises of the level 1 : [first\_wordchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word) [fizz\_buzzchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz) [\*ft\_putstrchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr) [\*ft\_strcpychevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy) [\*ft\_strlenchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen) [ft\_swapchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap) [repeat\_alphachevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha) [rev\_printchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print) [rot\_13chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13) [rotonechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone) [search\_and\_replacechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace) [ulstrchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr) We already know some of the functions (the ones with \* in front of them). [PreviousExam Rank 02chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02) [Nextfirst\_wordchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # rev_print | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print#subject) Subject Copy Assignment name : rev_print Expected files : rev_print.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string, and displays the string in reverse followed by a newline. If the number of parameters is not 1, the program displays a newline. Examples: $> ./rev_print "zaz" | cat -e zaz$ $> ./rev_print "dub0 a POIL" | cat -e LIOP a 0bud$ $> ./rev_print | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print#commented-solution) Commented solution chevron-rightrev\_print[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print#rev_print) [Previousrepeat\_alphachevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha) [Nextrot\_13chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print#commented-solution) sun-brightdesktopmoon rev\_print.c Copy #include <unistd.h> int main(int ac, char *av[]) { if (ac == 2) { int i; i = 0; /* looping over the whole string to find its length */ while (av[1][i]) i++; /* looping over the length of the string (length to 0) * and writing each character one by one */ while (i--) write(1, &av[1][i], 1); } write(1, "\n", 1); } sun-brightdesktopmoon --- # *ft_putstr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr#subject) Subject Copy Assignment name : ft_putstr Expected files : ft_putstr.c Allowed functions: write -------------------------------------------------------------------------------- Write a function that displays a string on the standard output. The pointer passed to the function contains the address of the string's first character. Your function must be declared as follows: void ft_putstr(char *str); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr#commented-solution) Commented solution chevron-rightft\_putstr[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr#ft_putstr) ft\_putstr.c Copy #include <unistd.h> void ft_putstr(char *str) { // Define and initialize an unsigned integer variable 'i' to 0 unsigned int i = 0; // Loop until the null character ('\0') is encountered in the string pointed to by 'str' while (str[i]) { // Call the 'write' function to output the character at the current position in the string, // specified by the value of 'i', to standard output (stdout) write(1, &str[i], 1); // Increment 'i' by 1 after each iteration i++; } } [Previousfizz\_buzzchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz) [Next\*ft\_strcpychevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr#commented-solution) sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_swap | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap#subject) Subject Copy Assignment name : ft_swap Expected files : ft_swap.c Allowed functions: -------------------------------------------------------------------------------- Write a function that swaps the contents of two integers the adresses of which are passed as parameters. Your function must be declared as follows: void ft_swap(int *a, int *b); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap#commented-solution) Commented solution chevron-rightft\_swap[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap#ft_swap) ft\_swap.c Copy void ft_swap(int *a, int *b) { /* we have to declare a temporary variable * to make a swap between 2 variables */ int x; // set our temporary variable to be equal to the value of *a x = *a; // set the value of *a to be equal to the value of *b *a = *b; // set the value of *b to be equal to the value of x *b = x; } [Previous\*ft\_strlenchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen) [Nextrepeat\_alphachevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap#commented-solution) sun-brightdesktopmoon sun-brightdesktopmoon --- # fizz_buzz | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz#subject) Subject Copy Assignment name : fizzbuzz Expected files : fizzbuzz.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that prints the numbers from 1 to 100, each separated by a newline. If the number is a multiple of 3, it prints 'fizz' instead. If the number is a multiple of 5, it prints 'buzz' instead. If the number is both a multiple of 3 and a multiple of 5, it prints 'fizzbuzz' instead. Example: $>./fizzbuzz 1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz [...] 97 98 fizz buzz $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz#commented-solution) Commented solution chevron-rightfizz\_buzz[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz#fizz_buzz) [Previousfirst\_wordchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word) [Next\*ft\_putstrchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz#commented-solution) sun-brightdesktopmoon fizz\_buzz.c Copy #include <unistd.h> /* we need to have a simple putnbr function for this one * since we'll be working with and printing numbers */ void ft_putnbr(int i) { /* if the number is greater than 9, we call the function again * with the number divided by 10 so that we remove one digit * from the end of it (123 => 12) */ if (i > 9) ft_putnbr(i / 10); /* then we can print the character at the index i % 10 (123 => 3) * in a string containing all digits from 0-9 */ write(1, &"0123456789"[i % 10], 1); /* I'll explain what I wrote above : * in C, strings do not exist, when we store a string * we store an array of character terminated by a NUL-character * so what I did above, is writing a string, and then I did * the same thing you'd do to select an array element with the * square bracket to select a specific index * the second argument of the write function is a char * * that's why I added the & character in front of the string * That way I give to write() a pointer to the specific * character I want to write */ } int main(void) { int i; i = 1; while (i <= 100) { if (i % 3 == 0 && i % 5 == 0) write(1, "fizzbuzz", 8); else if (i % 3 == 0) write(1, "fizz", 4); else if (i % 5 == 0) write(1, "buzz", 4); else ft_putnbr(i); i++; write(1, "\n", 1); } } sun-brightdesktopmoon --- # search_and_replace | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace#subject) Subject Copy Assignment name : search_and_replace Expected files : search_and_replace.c Allowed functions: write, exit -------------------------------------------------------------------------------- Write a program called search_and_replace that takes 3 arguments, the first arguments is a string in which to replace a letter (2nd argument) by another one (3rd argument). If the number of arguments is not 3, just display a newline. If the second argument is not contained in the first one (the string) then the program simply rewrites the string followed by a newline. Examples: $>./search_and_replace "Papache est un sabre" "a" "o" Popoche est un sobre $>./search_and_replace "zaz" "art" "zul" | cat -e $ $>./search_and_replace "zaz" "r" "u" | cat -e zaz$ $>./search_and_replace "jacob" "a" "b" "c" "e" | cat -e $ $>./search_and_replace "ZoZ eT Dovid oiME le METol." "o" "a" | cat -e ZaZ eT David aiME le METal.$ $>./search_and_replace "wNcOre Un ExEmPle Pas Facilw a Ecrirw " "w" "e" | cat -e eNcOre Un ExEmPle Pas Facile a Ecrire $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace#commented-solution) Commented solution chevron-rightsearch\_and\_replace[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace#search_and_replace) [Previousrotonechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone) [Nextulstrchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace#commented-solution) sun-brightdesktopmoon search\_and\_replace.c Copy #include <unistd.h> int main(int ac, char *av[]) { if (ac == 4) { int i; i = 0; /* loop over the whole string only if the second and * third argument are only one character */ while (av[1][i]) { /* if the current character is the one we have to * replace, we replace it by the third argument */ if (av[1][i] == av[2][0]) av[1][i] = av[3][0]; /* then we write the current character */ write(1, &av[1][i], 1); i++; } } /* at the very end we write a new line, that way we write * the new line everytime, whether we have enough argument or not */ write(1, "\n", 1); } sun-brightdesktopmoon --- # rotone | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone#subject) Subject Copy Assignment name : rotone Expected files : rotone.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it, replacing each of its letters by the next one in alphabetical order. 'z' becomes 'a' and 'Z' becomes 'A'. Case remains unaffected. The output will be followed by a \n. If the number of arguments is not 1, the program displays \n. Example: $>./rotone "abc" bcd $>./rotone "Les stagiaires du staff ne sentent pas toujours tres bon." | cat -e Mft tubhjbjsft ev tubgg of tfoufou qbt upvkpvst usft cpo.$ $>./rotone "AkjhZ zLKIJz , 23y " | cat -e BlkiA aMLJKa , 23z $ $>./rotone | cat -e $ $> $>./rotone "" | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone#commented-solution) Commented solution chevron-rightrotone[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone#rotone) [Previousrot\_13chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13) [Nextsearch\_and\_replacechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone#commented-solution) sun-brightdesktopmoon rotone.c Copy #include <unistd.h> int main(int ac, char *av[]) { if (ac == 2) { int i; i = 0; /* looping over the whole string */ while (av[1][i]) { /* checking if the character is Z or z * if it's the case, we remove 25 to get A or a * respectively */ if (av[1][i] == 90 || av[1][i] == 122) av[1][i] -= 25; /* checking if the character is between Aa - Yy * if it's the case, we can add 1 to it to get * the next character */ else if ((av[1][i] >= 65 && av[1][i] <= 89) || (av[1][i] >= 95 && av[1][i] <= 121)) av[1][i] += 1; /* finally, we can write the character and increment the * counter */ write(1, &av[1][i], 1); i++; } } write(1, "\n", 1); } sun-brightdesktopmoon --- # repeat_alpha | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha#subject) Subject Copy Assignment name : repeat_alpha Expected files : repeat_alpha.c Allowed functions: write -------------------------------------------------------------------------------- Write a program called repeat_alpha that takes a string and display it repeating each alphabetical character as many times as its alphabetical index, followed by a newline. 'a' becomes 'a', 'b' becomes 'bb', 'e' becomes 'eeeee', etc... Case remains unchanged. If the number of arguments is not 1, just display a newline. Examples: $>./repeat_alpha "abc" abbccc $>./repeat_alpha "Alex." | cat -e Alllllllllllleeeeexxxxxxxxxxxxxxxxxxxxxxxx.$ $>./repeat_alpha 'abacadaba 42!' | cat -e abbacccaddddabba 42!$ $>./repeat_alpha | cat -e $ $> $>./repeat_alpha "" | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha#commented-solution) Commented solution chevron-rightrepeat\_alpha[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha#repeat_alpha) [Previousft\_swapchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap) [Nextrev\_printchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/repeat_alpha#commented-solution) sun-brightdesktopmoon repeat\_alpha Copy #include <unistd.h> int main(int ac, char *av[]) { int i; int j; /* check the number of argument */ if (ac == 2) { i = 0; /* loop over the whole string */ while (av[1][i]) { /* if the character is an upper-case letter */ if (av[1][i] >= 65 && av[1][i] <= 90) { j = 0; /* loop while the j is smaller than the alphabetical * index of the current character * - 64 is to get the alphabetical index * A in ASCII => 65, so 65 - 64 = 1 * Z in ASCII => 90, so 90 - 64 = 26 */ while (j < av[1][i] - 64) { write(1, &av[1][i], 1); j++; } } else if (av[1][i] >= 97 && av[1][i] <= 122) { j = 0; /* loop while the j is smaller than the alphabetical * index of the current character * - 96 is to get the alphabetical index * a in ASCII => 97, so 97 - 96 = 1 * z in ASCII => 122, so 122 - 96 = 26 */ while (j < av[1][i] - 96) { write(1, &av[1][i], 1); j++; } } else /* if the current character is not a letter * simply write the character */ write(1, &av[1][i], 1); i++; } } write(1, "\n", 1); } sun-brightdesktopmoon --- # *ft_strcpy | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy#subject) Subject Copy Assignment name : ft_strcpy Expected files : ft_strcpy.c Allowed functions: -------------------------------------------------------------------------------- Reproduce the behavior of the function strcpy (man strcpy). Your function must be declared as follows: char *ft_strcpy(char *s1, char *s2); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy#commented-solution) Commented solution chevron-rightft\_strcpy[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy#ft_strcpy) ft\_strcpy.c Copy // man strcpy=> char *strcpy(char *dest, const char *src) char *ft_strcpy(char *s1, char *s2) { unsigned int i; i = 0; /* loop over the source string (s2) * if the source is empty, we don't even have to enter the loop */ while (s2[i]) { /* set the chracter at index i in the destination (s1) to be * equal to the character at index i in the source (s2) */ s1[i] = s2[i]; i++; } /* set the character at index i in the destination (s1) to 0 * this is done to NUL-terminate the destination (s1) if we copied * something inside * or to set the destination (s1) as empty if the source (s2) is empty */ s1[i] = 0; return (s1); } circle-check Thanks Veronique for the correction 😄 [Previous\*ft\_putstrchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_putstr) [Next\*ft\_strlenchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy#commented-solution) sun-brightdesktopmoon sun-brightdesktopmoon --- # *ft_strlen | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen#subject) Subject Copy Assignment name : ft_strlen Expected files : ft_strlen.c Allowed functions: -------------------------------------------------------------------------------- Write a function that returns the length of a string. Your function must be declared as follows: int ft_strlen(char *str); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen#commented-solution) Commented solution chevron-rightft\_strlen[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen#ft_strlen) I don't think I need to add any explanation, you know how this works, at least I hope so. ft\_strlen.c Copy int ft_strlen(char *str) { int i; i = 0; while (str[i]) i++; return (i); } [Previous\*ft\_strcpychevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strcpy) [Nextft\_swapchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_swap) Last updated 3 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ft_strlen#commented-solution) sun-brightdesktopmoon sun-brightdesktopmoon --- # first_word | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word#subject) Subject Copy Assignment name : first_word Expected files : first_word.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays its first word, followed by a newline. A word is a section of string delimited by spaces/tabs or by the start/end of the string. If the number of parameters is not 1, or if there are no words, simply display a newline. Examples: $> ./first_word "FOR PONY" | cat -e FOR$ $> ./first_word "this ... is sparta, then again, maybe not" | cat -e this$ $> ./first_word " " | cat -e $ $> ./first_word "a" "b" | cat -e $ $> ./first_word " lorem,ipsum " | cat -e lorem,ipsum$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word#commented-solution) Commented solution chevron-rightfirst\_word[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word#first_word) [PreviousLevel 1chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1) [Nextfizz\_buzzchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/fizz_buzz) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/first_word#commented-solution) sun-brightdesktopmoon first\_word.c Copy #include <unistd.h> int main(int ac, char *av[]) { /* checking the number of arguments */ if (argc == 2) { unsigned int i; i = 0; /* looping over the string to remove the possible starting * spaces (32) and tabulations (9) */ while (av[1][i] == 32 || av[1][i] == 9) i++; /* then start printing the characters from the string * until we find either a space, a tabulation, or a \0 */ while ((av[1][i] != 32 && av[1][i] != 9) && av[1][i]) write(1, &av[1][i++], 1); } /* writing a \n at the end, because in every case we have to put a * \n at then end, either when we wrote something or not */ write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # ulstr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr#subject) Subject Copy Assignment name : ulstr Expected files : ulstr.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and reverses the case of all its letters. Other characters remain unchanged. You must display the result followed by a '\n'. If the number of arguments is not 1, the program displays '\n'. Examples : $>./ulstr "L'eSPrit nE peUt plUs pRogResSer s'Il staGne et sI peRsIsTent VAnIte et auto-justification." | cat -e l'EspRIT Ne PEuT PLuS PrOGrESsER S'iL STAgNE ET Si PErSiStENT vaNiTE ET AUTO-JUSTIFICATION.$ $>./ulstr "S'enTOuRer dE sECreT eSt uN sIGnE De mAnQuE De coNNaiSSanCe. " | cat -e s'ENtoUrER De SecREt EsT Un SigNe dE MaNqUe dE COnnAIssANcE. $ $>./ulstr "3:21 Ba tOut moUn ki Ka di KE m'en Ka fe fot" | cat -e 3:21 bA ToUT MOuN KI kA DI ke M'EN kA FE FOT$ $>./ulstr | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr#commented-solution) Commented solution chevron-rightulstr[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr#ulstr) [Previoussearch\_and\_replacechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/search_and_replace) [NextLevel 2chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr#commented-solution) sun-brightdesktopmoon ulstr.c Copy #include <unistd.h> int main(int ac, char *av[]) { /* checking the number of argument */ if (ac == 2) { int i; i = 0; /* looping over the whole string */ while (av[1][i]) { /* if the character is an upper-case letter * add 32 to it to get the corresponding lower-case * letter */ if (av[1][i] >= 65 && av[1][i] <= 90) av[1][i] += 32; /* if the character is a lower-case letter * substract 32 from it to get the corresponding upper-case * letter */ else if (av[1][i] >= 97 && av[1][i] <= 122) av[1][i] -= 32; /* we can then write the current character and * increment i */ write(1, &av[1][i], 1); i++; } } /* at the very end, we write a new line, that way if the number * of argument is not correct, we'll write a single newline */ write(1, "\n", 1); } sun-brightdesktopmoon --- # rot_13 | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13#subject) Subject Copy Assignment name : rot_13 Expected files : rot_13.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it, replacing each of its letters by the letter 13 spaces ahead in alphabetical order. 'z' becomes 'm' and 'Z' becomes 'M'. Case remains unaffected. The output will be followed by a newline. If the number of arguments is not 1, the program displays a newline. Example: $>./rot_13 "abc" nop $>./rot_13 "My horse is Amazing." | cat -e Zl ubefr vf Nznmvat.$ $>./rot_13 "AkjhZ zLKIJz , 23y " | cat -e NxwuM mYXVWm , 23l $ $>./rot_13 | cat -e $ $> $>./rot_13 "" | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13#commented-solution) Commented solution chevron-rightrot\_13[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13#rot_13) [Previousrev\_printchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rev_print) [Nextrotonechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rotone) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/rot_13#commented-solution) sun-brightdesktopmoon rot\_13.c Copy #include <unistd.h> int main(int ac, char *av[]) { if (ac == 2) { int i; i = 0; /* looping over the whole string */ while (av[1][i]) { /* checking if the character is between Aa - Mm * if it's the case, we can add 13 to it to get * the character 13 places in front of it */ if ((av[1][i] >= 65 && av[1][i] <= 77) || (av[1][i] >= 97 && av[1][i] <= 109)) av[1][i] += 13; /* checking if the character is between Nn - Zz * if it's the case, we can substract 13 to it to get * the character 13 places in front of it */ else if ((av[1][i] >= 78 && av[1][i] <= 90) || (av[1][i] >= 110 && av[1][i] <= 122)) av[1][i] -= 13; /* finally, we can write the character and increment the * counter */ write(1, &av[1][i], 1); i++; } } write(1, "\n", 1); } sun-brightdesktopmoon --- # Level 4 | Guide Here are the 10 exercises of level 4: [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/flood\_fill.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/flood_fill.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/fprime.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/fprime.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft\_itoa.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft_itoa.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft\_list\_foreach.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft_list_foreach.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft\_list\_remove\_if.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft_list_remove_if.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft\_split.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/ft_split.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/rev\_wstr.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/rev_wstr.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/rostring.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/rostring.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/sort\_int\_tab.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/sort_int_tab.md) [https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/sort\_list.mdchevron-right](https://github.com/thebrisly/42-guide-website/blob/main/exams/exam-rank-02/level-4/sort_list.md) [Previoustab\_multchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult) [Nextflood\_filchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil) Last updated 10 months ago sun-brightdesktopmoon sun-brightdesktopmoon --- # fprime | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime#subject) Subject Copy Assignment name : fprime Expected files : fprime.c Allowed functions: printf, atoi -------------------------------------------------------------------------------- Write a program that takes a positive int and displays its prime factors on the standard output, followed by a newline. Factors must be displayed in ascending order and separated by '*', so that the expression in the output gives the right result. If the number of parameters is not 1, simply display a newline. The input, when there is one, will be valid. Examples: $> ./fprime 225225 | cat -e 3*3*5*5*7*11*13$ $> ./fprime 8333325 | cat -e 3*3*5*5*7*11*13*37$ $> ./fprime 9539 | cat -e 9539$ $> ./fprime 804577 | cat -e 804577$ $> ./fprime 42 | cat -e 2*3*7$ $> ./fprime 1 | cat -e 1$ $> ./fprime | cat -e $ $> ./fprime 42 21 | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime#commented-solution) Commented solution chevron-rightfprime[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime#fprime) [Previousflood\_filchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil) [Nextft\_splitchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fr_split) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime#commented-solution) sun-brightdesktopmoon fprime.c Copy #include "stdio.h" #include "stdlib.h" int main(int ac, char **av) { int i; int num; i = 2; if (ac == 2) { num = atoi(av[1]); if (num == 1) printf("1"); while (i <= num) { if (num % i == 0) { printf("%d", i); if (num != i) printf("*"); num = num / i; } else i++; } } printf("\n"); return (0); } sun-brightdesktopmoon --- # rotstring | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring#subject) Subject Copy Copy Assignment name : rostring Expected files : rostring.c Allowed functions: write, malloc, free -------------------------------------------------------------------------------- Write a program that takes a string and displays this string after rotating it one word to the left. Thus, the first word becomes the last, and others stay in the same order. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. Words will be separated by only one space in the output. If there's less than one argument, the program displays \n. Example: $>./rostring "abc " | cat -e abc$ $> $>./rostring "Que la lumiere soit et la lumiere fut" la lumiere soit et la lumiere fut Que $> $>./rostring " AkjhZ zLKIJz , 23y" zLKIJz , 23y AkjhZ $> $>./rostring "first" "2" "11000000" first $> $>./rostring | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring#commented-solution) Commented solution chevron-rightrostring[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring#rostring) [Previousrev\_wstrchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr) [Nextsort\_int\_tabchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring#commented-solution) sun-brightdesktopmoon rostring.c Copy #include "unistd.h" void rostring(char *str) { int i; int j; i = 0; while (str[i] && str[i] == ' ' || str[i] == '\t') i++; j = i; while (str[i]) { while (str[i] && str[i] != ' ' && str[i] != '\t') i++; while (str[i] && (str[i] == ' ' || str[i] == '\t')) i++; while ((str[i] && (str[i] != ' ' && str[i] != '\t')) && (str[i\ - 1] == ' ' || str[i - 1] == '\t')) { while (str[i] && (str[i] != ' ' && str[i] != '\t')) { write(1, &str[i], 1); i++; } write(1, " ", 1); i++; } } while (str[j] && (str[j] != ' ' && str[j] != '\t')) { write(1, &str[j], 1); j++; } } int main(int ac, char **av) { if (ac >= 2) { rostring(av[1]); } write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # ft_list_foreach | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach#subject) Subject Copy Copy Assignment name : ft_list_foreach Expected files : ft_list_foreach.c, ft_list.h Allowed functions: -------------------------------------------------------------------------------- Write a function that takes a list and a function pointer, and applies this function to each element of the list. It must be declared as follows: void ft_list_foreach(t_list *begin_list, void (*f)(void *)); The function pointed to by f will be used as follows: (*f)(list_ptr->data); You must use the following structure, and turn it in as a file called ft_list.h: typedef struct s_list { struct s_list *next; void *data; } t_list; ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach#commented-solution) Commented solution chevron-rightft\_list\_foreach[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach#ft_list_foreach) [Previousft\_itoachevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa) [Nextft\_list\_removechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach#commented-solution) sun-brightdesktopmoon ft\_list\_foreach.c Copy // You must use the following structure, and turn it in as a file called ft_list.h: typedef struct s_list { struct s_list *next; void *data; } t_list; #include "stddef.h" void ft_list_foreach(t_list *begin_list, void (*f)(void *)) { while (begin_list != NULL) { if (begin_list->data != NULL) (*f)(begin_list->data); begin_list = begin_list->next; } } sun-brightdesktopmoon --- # sort_int_tab | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab#subject) Subject Copy Copy Assignment name : sort_int_tab Expected files : sort_int_tab.c Allowed functions: -------------------------------------------------------------------------------- Write the following function: void sort_int_tab(int *tab, unsigned int size); It must sort (in-place) the 'tab' int array, that contains exactly 'size' members, in ascending order. Doubles must be preserved. Input is always coherent. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab#commented-solution) Commented solution chevron-rightsort\_int\_tab[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab#sort_int_tab) [Previousrotstringchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring) [Nextsort\_listchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab#commented-solution) sun-brightdesktopmoon sort\_int\_tab.c Copy void sort_int_tab(int *tab, unsigned int size) { int tmp; unsigned int i; unsigned int j; i = 0; while (i < size - 1) { j = i; while (j < size) { if (tab[i] > tab[j]) { tmp = tab[i]; tab[i] = tab[j]; tab[j] = tmp; } j++; } i++; } } sun-brightdesktopmoon --- # ft_list_remove | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if#subject) Subject Copy Copy Assignment name : ft_list_remove_if Expected files : ft_list_remove_if.c Allowed functions: free -------------------------------------------------------------------------------- Write a function called ft_list_remove_if that removes from the passed list any element the data of which is "equal" to the reference data. It will be declared as follows : void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)()); cmp takes two void* and returns 0 when both parameters are equal. You have to use the ft_list.h file, which will contain: $>cat ft_list.h typedef struct s_list { struct s_list *next; void *data; } t_list; $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if#commented-solution) Commented solution chevron-rightft\_list\_remove\_if[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if#ft_list_remove_if) [Previousft\_list\_foreachchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach) [Nextrev\_wstrchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if#commented-solution) sun-brightdesktopmoon ft\_list\_remove\_if.c Copy // You have to use the ft_list.h file, which will contain: ft_list.h typedef struct s_list { struct s_list *next; void *data; } t_list; #include "ft_list.h" #include "stdlib.h" void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)()) { t_list *tmp; if ((*begin_list == NULL) || (begin_list == NULL)) return ; if (cmp((*begin_list)->data, data_ref) == 0x0) { tmp = *begin_list; *begin_list = (*begin_list)->next; free(tmp); ft_list_remove_if(begin_list, data_ref, cmp); } else ft_list_remove_if(&((*begin_list)->next), data_ref, cmp); } sun-brightdesktopmoon --- # rev_wstr | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr#subject) Subject Copy Copy Assignment name : rev_wstr Expected files : rev_wstr.c Allowed functions: write, malloc, free -------------------------------------------------------------------------------- Write a program that takes a string as a parameter, and prints its words in reverse order. A "word" is a part of the string bounded by spaces and/or tabs, or the begin/end of the string. If the number of parameters is different from 1, the program will display '\n'. In the parameters that are going to be tested, there won't be any "additional" spaces (meaning that there won't be additionnal spaces at the beginning or at the end of the string, and words will always be separated by exactly one space). Examples: $> ./rev_wstr "You hate people! But I love gatherings. Isn't it ironic?" | cat -e ironic? it Isn't gatherings. love I But people! hate You$ $>./rev_wstr "abcdefghijklm" abcdefghijklm $> ./rev_wstr "Wingardium Leviosa" | cat -e Leviosa Wingardium$ $> ./rev_wstr | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr#commented-solution) Commented solution chevron-rightrev\_wstr[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr#rev_wstr) [Previousft\_list\_removechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_remove_if) [Nextrotstringchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rostring) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/rev_wstr#commented-solution) sun-brightdesktopmoon rev\_wstr.c Copy #include "unistd.h" int main(int ac, char **av) { int i; int j; int first_word; i = 0; first_word = 0; if (ac == 2) { while (av[1][i] != '\0') i++; i--; while (i >= 0) { while (i >= 0 && (av[1][i] == ' ' || av[1][i] == '\t')) i--; j = i; while (j >= 0 && av[1][j] != ' ' && av[1][j] != '\t') j--; if (first_word) write(1, " ", 1); write(1, &av[1][j + 1], i - j); first_word = 1; i = j; } } write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # sort_list | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list#subject) Subject Copy Copy Assignment name : sort_list Expected files : sort_list.c Allowed functions: -------------------------------------------------------------------------------- Write the following functions: t_list *sort_list(t_list* lst, int (*cmp)(int, int)); This function must sort the list given as a parameter, using the function pointer cmp to select the order to apply, and returns a pointer to the first element of the sorted list. Duplications must remain. Inputs will always be consistent. You must use the type t_list described in the file list.h that is provided to you. You must include that file (#include "list.h"), but you must not turn it in. We will use our own to compile your assignment. Functions passed as cmp will always return a value different from 0 if a and b are in the right order, 0 otherwise. For example, the following function used as cmp will sort the list in ascending order: int ascending(int a, int b) { return (a <= b); } ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list#commented-solution) Commented solution chevron-rightsort\_list[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list#sort_list) [Previoussort\_int\_tabchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_int_tab) [NextExam Rank 03chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-03) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/sort_list#commented-solution) sun-brightdesktopmoon sort\_list.c Copy #include "list.h" #include "unistd.h" t_list *sort_list(t_list *lst, int (*cmp)(int, int)) { int tmp; t_list *head; head = tmp; while (lst != NULL && lst->next != NULL) { if ((*cmp)(lst->data, lst->next->data) == 0) { tmp = lst->data; lst->data = lst->next->data; lst->next->data = tmp; lst = head; } else lst = lst->next; } return (head); } sun-brightdesktopmoon --- # Level 3 | Guide Here are the 15 exercises of level 3: [add\_prime\_sumchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum) [epur\_strchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str) [expand\_strchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str) [ft\_atoi\_basechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base) [ft\_list\_sizechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size) [ft\_rangechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range) [ft\_rrangechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange) [hidenpchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp) [lcmchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm) [paramsumchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum) [pgcdchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd) [print\_hexchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex) [rstr\_capitalizerchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer) [str\_capitalizerchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer) [tab\_multchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult) [Previoussnake\_to\_camelchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/snake_to_camel) [Nextadd\_prime\_sumchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum) Last updated 3 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_rrange | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange#subject) Subject Copy Assignment name : ft_rrange Expected files : ft_rrange.c Allowed functions: malloc -------------------------------------------------------------------------------- Write the following function: int *ft_rrange(int start, int end); It must allocate (with malloc()) an array of integers, fill it with consecutive values that begin at end and end at start (Including start and end !), then return a pointer to the first value of the array. Examples: - With (1, 3) you will return an array containing 3, 2 and 1 - With (-1, 2) you will return an array containing 2, 1, 0 and -1. - With (0, 0) you will return an array containing 0. - With (0, -3) you will return an array containing -3, -2, -1 and 0. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange#commented-solution) Commented solution chevron-rightft\_rrange()[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange#ft_rrange) [Previousft\_rangechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range) [Nexthidenpchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange#commented-solution) sun-brightdesktopmoon ft\_rrange.c Copy int *ft_rrange(int start, int end) { int i = 0; // Defining the length of the range // Since we don't have access to the abse function, we have // to make a manual absolute value int len = (end - start) < 0 ? ((end - start) * -1) + 1 : (end - start) + 1; // Allocating the range needed int *range = (int *) malloc(len * sizeof(int)); // Fill in the range while (i < len) { // Next lines are for numbers going up if (end < start) range[i] = end++; // Next lines are for numbers going down else range[i] = end--; i++; } // Returning the filled range return (range); } sun-brightdesktopmoon --- # ft_range | Guide [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range#subject) Subject ------------------------------------------------------------------------------------------------------ Copy Assignment name : ft_range Expected files : ft_range.c Allowed functions: malloc -------------------------------------------------------------------------------- Write the following function: int *ft_range(int start, int end); It must allocate (with malloc()) an array of integers, fill it with consecutive values that begin at start and end at end (Including start and end !), then return a pointer to the first value of the array. Examples: - With (1, 3) you will return an array containing 1, 2 and 3. - With (-1, 2) you will return an array containing -1, 0, 1 and 2. - With (0, 0) you will return an array containing 0. - With (0, -3) you will return an array containing 0, -1, -2 and -3. [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range#commented-solution) Commented solution ---------------------------------------------------------------------------------------------------------------------------- chevron-rightft\_range.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range#ft_range.c) [Previousft\_list\_sizechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size) [Nextft\_rrangechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range#commented-solution) sun-brightdesktopmoon ft\_range.c Copy int *ft_range(int start, int end) { int i = 0; // Defining the lenght of the range // Since we don't have access to the abs function, we have // to make a manual absolute value int len = (end - start) < 0 ? ((end - start) * -1) + 1 : (end - start) + 1; // Allocating the range needed int *range = (int *) malloc(len * sizeof(int)); // Fill in the range while (i < len) { // Next lines are for numbers going up if (start < end) range[i] = start++; // Next lines are for numbers going down else range[i] = start--; i++; } // Returning the filled range return (range); } sun-brightdesktopmoon --- # ft_list_size | Guide [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size#subject) Subject ---------------------------------------------------------------------------------------------------------- Copy Assignment name : ft_list_size Expected files : ft_list_size.c, ft_list.h Allowed functions: -------------------------------------------------------------------------------- Write a function that returns the number of elements in the linked list that's passed to it. It must be declared as follows: int ft_list_size(t_list *begin_list); You must use the following structure, and turn it in as a file called ft_list.h: typedef struct s_list { struct s_list *next; void *data; } t_list; [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size#commented-solution) Commented solution -------------------------------------------------------------------------------------------------------------------------------- circle-exclamation Don't forget to turn in your `ft_list.h` file as well chevron-rightft\_list\_size()[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size#ft_list_size) [Previousft\_atoi\_basechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base) [Nextft\_rangechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_range) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size#commented-solution) sun-brightdesktopmoon ft\_list\_size.c Copy #include "ft_list.h" int ft_list_size(t_list *begin_list) { int i = 0; // Loop over list elements while the next element is not null while (begin_list->next) { // set the original pointer equal to a pointer to the // next element and increment our counter begin_list = begin_list->next; i++; } // return the counter return (i); } sun-brightdesktopmoon --- # flood_fil | Guide if you have never had to deal with this kind of problem, I advise you to watch this video which explains the principle VERY WELL! Just after that, you'll be able to code flood fill in 5 minutes ;) And here is the subject: ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil#subject) Subject ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil#commented-solution) Commented solution flood\_fill You can then use the example of the subject to see if you did everything right :-) [PreviousLevel 4chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4) [Nextfprimechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fprime) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/flood_fil#commented-solution) sun-brightdesktopmoon Copy Copy Assignment name : flood_fill Expected files : *.c, *.h Allowed functions: - -------------------------------------------------------------------------------- Write a function that takes a char ** as a 2-dimensional array of char, a t_point as the dimensions of this array and a t_point as the starting point. Starting from the given 'begin' t_point, this function fills an entire zone by replacing characters inside with the character 'F'. A zone is an group of the same character delimitated horizontally and vertically by other characters or the array boundry. The flood_fill function won't fill diagonally. The flood_fill function will be prototyped like this: void flood_fill(char **tab, t_point size, t_point begin); The t_point structure is prototyped like this: typedef struct s_point { int x; int y; } t_point; Example: $> cat test_main.c #include "test_functions.h" #include "flood_fill.h" int main(void) { char **area; t_point size = {8, 5}; t_point begin = {2, 2}; char *zone[] = { "1 1 1 1 1 1 1 1", "1 0 0 0 1 0 0 1", "1 0 0 1 0 0 0 1", "1 0 1 1 0 0 0 1", "1 1 1 0 0 0 0 1", } area = make_area(zone); print_tab(area); flood_fill(area, size, begin); putc('\n'); print_tab(area); return (0); } $> gcc flood_fill.c test_main.c test_functions.c -o flood_fill; ./flood_fill 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 F F F 1 0 0 1 1 F F 1 0 0 0 1 1 F 1 0 0 0 0 1 1 1 0 0 0 0 0 0 $> ------------------------------------------------------------------------------*/ flood\_fill.c Copy #include "flood_fill.h" // Recursive function to flood fill an area of a 2D character array void fill(char **tab, t_point size, char target, int row, int col) { // Check if current row and column values are out of bounds if (row < 0 || col < 0 || row >= size.y || col >= size.x) return; // Check if current cell has already been filled or does not match the target character if (tab[row][col] == 'F' || tab[row][col] != target) return; // Mark current cell as filled tab[row][col] = 'F'; // Recursively fill neighboring cells fill(tab, size, target, row -1, col); // fill cell above fill(tab, size, target, row +1, col); // fill cell below fill(tab, size, target, row, col - 1); // fill cell to the left fill(tab, size, target, row, col + 1); // fill cell to the right } // Function to initiate flood fill from a specified point void flood_fill(char **tab, t_point size, t_point begin) { char target = tab[begin.y][begin.x]; // Get the character to fill around fill(tab, size, target, begin.y, begin.x); // Start the flood fill from the specified point } sun-brightdesktopmoon --- # hidenp | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp#subject) Subject Copy Assignment name : hidenp Expected files : hidenp.c Allowed functions: write -------------------------------------------------------------------------------- Write a program named hidenp that takes two strings and displays 1 followed by a newline if the first string is hidden in the second one, otherwise displays 0 followed by a newline. Let s1 and s2 be strings. We say that s1 is hidden in s2 if it's possible to find each character from s1 in s2, in the same order as they appear in s1. Also, the empty string is hidden in any string. If the number of parameters is not 2, the program displays a newline. Examples : $>./hidenp "fgex.;" "tyf34gdgf;'ektufjhgdgex.;.;rtjynur6" | cat -e 1$ $>./hidenp "abc" "2altrb53c.sse" | cat -e 1$ $>./hidenp "abc" "btarc" | cat -e 0$ $>./hidenp | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp#commented-solution) Commented solution chevron-righthidenp[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp#hidenp) [Previousft\_rrangechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_rrange) [Nextlcmchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp#commented-solution) sun-brightdesktopmoon hidenp.c Copy #include <unistd.h> int main(int ac, char **av) { int i = 0, j = 0; if (ac == 3) { // Looping over s2 only if there is something // in s1 while (av[2][j] && av[1][i]) { // If current char of s2 equals current char // of s1, advance in s1 if (av[2][j] == av[1][i]) i++; // advance in s2 every time j++; } // if we reached the end of s1, it's hidden in s2 if (av[1][i] == 0) write(1, "1", 1); else write(1, "0", 1); } write(1, "\n", 1); } sun-brightdesktopmoon --- # lcm | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm#subject) Subject Copy Assignment name : lcm Expected files : lcm.c Allowed functions: -------------------------------------------------------------------------------- Write a function who takes two unsigned int as parameters and returns the computed LCM of those parameters. LCM (Lowest Common Multiple) of two non-zero integers is the smallest postive integer divisible by the both integers. A LCM can be calculated in two ways: - You can calculate every multiples of each integers until you have a common multiple other than 0 - You can use the HCF (Highest Common Factor) of these two integers and calculate as follows: LCM(x, y) = | x * y | / HCF(x, y) | x * y | means "Absolute value of the product of x by y" If at least one integer is null, LCM is equal to 0. Your function must be prototyped as follows: unsigned int lcm(unsigned int a, unsigned int b); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm#commented-solution) Commented solution chevron-rightlcm[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm#lcm) [Previoushidenpchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/hidenp) [Nextparamsumchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm#commented-solution) sun-brightdesktopmoon lcm.c Copy unsigned int lcm(unsigned int a, unsigned int b) { unsigned int g = (a > b) ? a : b; // Check if any of the integer is null if (a == 0 || b == 0) return (0); while (1) { // if g is perfectly divisible by both a and b // this is the lcm if ((g % a == 0) && (g % b == 0)) return (g); g++; } } // Un-comment the following to test // #include <stdio.h> // #include <stdlib.h> // int main(int ac, char **av) // { // if (ac == 3) // { // unsigned int m = lcm(atoi(av[1]), atoi(av[2])); // printf("LCM: %u\n", m); // } // } sun-brightdesktopmoon --- # add_prime_sum | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum#subject) Subject Copy Assignment name : add_prime_sum Expected files : add_prime_sum.c Allowed functions: write, exit -------------------------------------------------------------------------------- Write a program that takes a positive integer as argument and displays the sum of all prime numbers inferior or equal to it followed by a newline. If the number of arguments is not 1, or the argument is not a positive number, just display 0 followed by a newline. Yes, the examples are right. Examples: $>./add_prime_sum 5 10 $>./add_prime_sum 7 | cat -e 17$ $>./add_prime_sum | cat -e 0$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum#commented-solution) Commented solution There's actually nothing really complicated in the fact of making a simple addition between some numbers, the real challenge is to build the supportive function, hope you remember how to build an `atoi` function. chevron-rightadd\_prime\_sum.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum#add_prime_sum.c) [PreviousLevel 3chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3) [Nextepur\_strchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum#commented-solution) sun-brightdesktopmoon add\_prime\_sum.c Copy #include <unistd.h> void ft_putchar(char c); void ft_putnbr(int nbr); int is_prime(int nbr); int ft_atoi(char *str); void ft_putchar(char c) { write(1, &c, 1); } void ft_putnbr(int nbr) { unsigned int nb; if (nbr < 0) { ft_putchar('-'); nb = -nbr; } else nb = nbr; if (nb >= 10) ft_putnbr(nb / 10); ft_putchar(nb % 10 + '0'); } // checking if a number is a prime number int is_prime(int nbr) { // first prime number is 3, if nbr smaller than that we // can return 0 to say it's not prime if (nbr < 2) return (0); // checking all factors up until half nbr // going over nbr/2 is useless, let's take an example // nbr = 10; nbr/2 = 5; If we check for 3, checking for 6 // will give the same result int i = 2; while (i <= nbr / 2) { if (nbr % i == 0) return (0); i++; } return (1); } // You know how this works int ft_atoi(char *str) { int res = 0, sign = 1, i = 0; while (str[i] == ' ') i++; if (str[i] == '+' || str[i] == '-') if (str[i++] == '-') sign = -1; while (str[i] && str[i] >= 48 && str[i] <= 57) { res *= 10; res += str[i] - 48; i++; } res *= sign; return (res); } int main(int ac, char **av) { if (ac != 2 || ft_atoi(av[1]) <= 0) { write(1, "0\n", 2); return (0); } int n = ft_atoi(av[1]); // The following is the actual logic for add_prime_sum // we check every number up until what's given via the // command line and if the number is prime, we add it // to the whole sum. int sum = 0; while (n > 1) { if (is_prime(n)) sum += n; n--; } ft_putnbr(sum); ft_putchar('\n'); } sun-brightdesktopmoon --- # expand_str | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str#subject) Subject Copy Assignment name : expand_str Expected files : expand_str.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it with exactly three spaces between each word, with no spaces or tabs either at the beginning or the end, followed by a newline. A word is a section of string delimited either by spaces/tabs, or by the start/end of the string. If the number of parameters is not 1, or if there are no words, simply display a newline. Examples: $> ./expand_str "vous voyez c'est facile d'afficher la meme chose" | cat -e vous voyez c'est facile d'afficher la meme chose$ $> ./expand_str " seulement la c'est plus dur " | cat -e seulement la c'est plus dur$ $> ./expand_str "comme c'est cocasse" "vous avez entendu, Mathilde ?" | cat -e $ $> ./expand_str "" | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str#commented-solution) Commented solution chevron-rightexpand\_str[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str#expand_str) [Previousepur\_strchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str) [Nextft\_atoi\_basechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str#commented-solution) sun-brightdesktopmoon expand\_str.c Copy #include <unistd.h> void ft_putchar(char c) { write(1, &c, 1); } int is_space(char c) { if (c <= 32) return 1; return 0; } int main(int ac, char **av) { if (ac == 2) { int i = 0, space = 0; // skipping all leading blank chars while (is_space(av[1][i])) i++; while (av[1][i]) { // if there is a blank char, make the space flag 1 // if there are multiple blank, it will be set // to 1 each time if (is_space(av[1][i])) space = 1; // if current char is not a blank char // write 3 spaces if flag is on // set the space flag back to 0 // write current char if (!is_space(av[1][i])) { if (space) write(1, " ", 3); space = 0; ft_putchar(av[1][i]); } i++; } } ft_putchar('\n'); } sun-brightdesktopmoon --- # epur_str | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str#subject) Subject Copy Assignment name : epur_str Expected files : epur_str.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string, and displays this string with exactly one space between words, with no spaces or tabs either at the beginning or the end, followed by a \n. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. If the number of arguments is not 1, or if there are no words to display, the program displays \n. Example: $> ./epur_str "vous voyez c'est facile d'afficher la meme chose" | cat -e vous voyez c'est facile d'afficher la meme chose$ $> ./epur_str " seulement la c'est plus dur " | cat -e seulement la c'est plus dur$ $> ./epur_str "comme c'est cocasse" "vous avez entendu, Mathilde ?" | cat -e $ $> ./epur_str "" | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str#commented-solution) Commented solution chevron-rightepur\_str[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str#epur_str) [Previousadd\_prime\_sumchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/add_prime_sum) [Nextexpand\_strchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/epur_str#commented-solution) sun-brightdesktopmoon epur\_str.c Copy #include <unistd.h> void ft_putchar(char c) { write(1, &c, 1); } int is_space(char c) { if (c <= 32) return 1; return 0; } int main(int ac, char **av) { if (ac == 2) { int i = 0, space = 0; // skipping all leading blank chars while (is_space(av[1][i])) i++; while (av[1][i]) { // if there is a blank char, make the space flag 1 // if there are multiple blank, it will be set // to 1 each time if (is_space(av[1][i])) space = 1; // if current char is not a blank char // write a space if flag is on // set the space flag back to 0 // write current char if (!is_space(av[1][i])) { if (space) ft_putchar(' '); space = 0; ft_putchar(av[1][i]); } i++; } } ft_putchar('\n'); } sun-brightdesktopmoon --- # ft_atoi_base | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base#subject) Subject Copy Assignment name : ft_atoi_base Expected files : ft_atoi_base.c Allowed functions: None -------------------------------------------------------------------------------- Write a function that converts the string argument str (base N <= 16) to an integer (base 10) and returns it. The characters recognized in the input are: 0123456789abcdef Those are, of course, to be trimmed according to the requested base. For example, base 4 recognizes "0123" and base 16 recognizes "0123456789abcdef". Uppercase letters must also be recognized: "12fdb3" is the same as "12FDB3". Minus signs ('-') are interpreted only if they are the first character of the string. Your function must be declared as follows: int ft_atoi_base(const char *str, int str_base); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base#commented-solution) Commented solution chevron-rightft\_atoi\_base[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base#ft_atoi_base) [Previousexpand\_strchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/expand_str) [Nextft\_list\_sizechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_list_size) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/ft_atoi_base#commented-solution) sun-brightdesktopmoon ft\_atoi\_base() Copy int ft_atoi_base(const char *str, int str_base); int isspace(int c); int isvalid(int c, int baselen); int ft_atoi_base(const char *str, int str_base) { int res = 0, sign = 1, i = 0; // Skip the whitespaces while (isspace(str[i]) i++; // Check if the number is negative if (str[i] == '+' && str[i + 1] != '-') i++; // If the number is negative, set the sign to -1 and skip the '-' if (str[i] == '-') { sign = -1; i++; } // Loop through the string and convert the numebr to base 10 while (str[i] && isvalid(str[i], str_base)) { // Multiply the result by the base res *= str_base; // Add the value of the character to the result // If the character is a digit, substract the value of '0' // from it // i.e. '5' - '0' = 5 because the ASCII value of '5' is 53 // and the ASCII value of '0' is 48 if (str[i] >= '0' && str[i] <= 9) res += str[i] - '0'; // If the character is a leter, substract the value of 'a' or // 'A' from it and add 10 // i.e. 'f' - 'a' + 10 = 15 because the ASCII value of 'f' is // 102 and the ASCII value of 'a' is 97 else if (str[i] >= 'a' && str[i] <= 'f') res += str[i] - 'a' + 10; else if (str[i] >= 'A' && str[i] <= 'F') res += str[i] - 'A' + 10; i++; } // Return the result multiplied by the sign return (res * sign); } // Simple function to check if the character is valid for the base int isvalid(int ch, int baselen) { // Define the base char *lcbase = "0123456789abcdef"; char *ucbase = "0123456789ABCDEF"; int i = 0; // Loop through the base and check if the character is valid while (i < baselen) { // If the character is found in the base, return 1 if (ch == lcbase[i] || ch == ucbase[i]) return (1); i++; } return (0); } // Simple function to check if the character is a whitespace int isspace(int c) { if (c == 9 || c == 10 || c == 11 || c == 12 || c == 13 || c == 32) return (1); return (0); } // Uncomment the main to test the function // #include <stdio.h> // int main(int ac, char **av) // { // (void) ac; // (void) av; // if (ac == 3) // { // printf("%d", ft_atoi_base(av[1], ft_atoi_base(av[2], 10))); // return (0); // } // } sun-brightdesktopmoon --- # str_capitalizer | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer#subject) Subject Copy Assignment name : str_capitalizer Expected files : str_capitalizer.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes one or several strings and, for each argument, capitalizes the first character of each word (If it's a letter, obviously), puts the rest in lowercase, and displays the result on the standard output, followed by a \n. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. If a word only has one letter, it must be capitalized. If there are no arguments, the progam must display \n. Example: $> ./str_capitalizer | cat -e $ $> ./str_capitalizer "a FiRSt LiTTlE TESt" | cat -e A First Little Test$ $> ./str_capitalizer "__SecONd teST A LITtle BiT Moar comPLEX" " But... This iS not THAT COMPLEX" " Okay, this is the last 1239809147801 but not the least t" | cat -e __second Test A Little Bit Moar Complex$ But... This Is Not That Complex$ Okay, This Is The Last 1239809147801 But Not The Least T$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer#commented-solution) Commented solution chevron-rightstr\_capitalizer[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer#str_capitalizer) [Previousrstr\_capitalizerchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer) [Nexttab\_multchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer#commented-solution) sun-brightdesktopmoon str\_capitalizer.c Copy #include <unistd.h> int ft_isspace(char c) { if (c <= 32) return (1); return (0); } void ft_putchar(char c) { write(1, &c, 1); } void capitalizer(char *s) { int i = 0; while (s[i]) { // If the character is uppercase, make it lowercase if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32; // Now check for lowercase character and if the previous char // is a space character, make it uppercase again if ((s[i] >= 'a' && s[i] <= 'z') && ft_isspace(s[i - 1])) s[i] -= 32; // Now print every char ft_putchar(s[i++]); } } int main(int ac, char **av) { int i = 1; if (ac == 1) ft_putchar('\n'); else { // Loop over all params starting at 1 (we don't want the name of // the executable to be written to the screen) while (i < ac) { capitalizer(av[i]); ft_putchar('\n'); i++; } } } sun-brightdesktopmoon --- # print_hex | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex#subject) Subject Copy Assignment name : print_hex Expected files : print_hex.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a positive (or zero) number expressed in base 10, and displays it in base 16 (lowercase letters) followed by a newline. If the number of parameters is not 1, the program displays a newline. Examples: $> ./print_hex "10" | cat -e a$ $> ./print_hex "255" | cat -e ff$ $> ./print_hex "5156454" | cat -e 4eae66$ $> ./print_hex | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex#commented-solution) Commented solution chevron-rightprint\_hex.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex#print_hex.c) [Previouspgcdchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd) [Nextrstr\_capitalizerchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex#commented-solution) sun-brightdesktopmoon print\_hex.c Copy #include <unistd.h> // Simple atoi to convert the parameter to unsigned int // You might need to manage negative numbers and all of // that, it isn't specified in the subject if they could // be sent to your program or not unsigned int ft_atoi(char *str) { unsigned int res = 0, i = 0; while (str[i] && str[i] >= '0' && str[i] <= '9') { res *= 10; res += str[i++] - '0'; } return (res); } void put_hex(int nbr) { char *digits = "0123456789abcdef"; if (nbr >= 16) put_hex(nbr / 16); // choosing the char corresponding to the number we want // and writing it to the screen nbr = digits[nbr % 16]; write(1, &nbr, 1); } int main(int ac, char **av) { // if there is an argument, send it directly to the // put_hex function via ft_atoi if (ac == 2) put_hex(ft_atoi(av[1])); write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # rstr_capitalizer | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer#subject) Subject Copy Assignment name : rstr_capitalizer Expected files : rstr_capitalizer.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes one or more strings and, for each argument, puts the last character that is a letter of each word in uppercase and the rest in lowercase, then displays the result followed by a \n. A word is a section of string delimited by spaces/tabs or the start/end of the string. If a word has a single letter, it must be capitalized. A letter is a character in the set [a-zA-Z] If there are no parameters, display \n. Examples: $> ./rstr_capitalizer | cat -e $ $> ./rstr_capitalizer "a FiRSt LiTTlE TESt" | cat -e A firsT littlE tesT$ $> ./rstr_capitalizer "SecONd teST A LITtle BiT Moar comPLEX" " But... This iS not THAT COMPLEX" " Okay, this is the last 1239809147801 but not the least t" | cat -e seconD tesT A littlE biT moaR compleX$ but... thiS iS noT thaT compleX$ okay, thiS iS thE lasT 1239809147801 buT noT thE leasT T$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer#commented-solution) Commented solution chevron-rightrstr\_capitalizer[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer#rstr_capitalizer) [Previousprint\_hexchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex) [Nextstr\_capitalizerchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/rstr_capitalizer#commented-solution) sun-brightdesktopmoon rstr\_capitalizer.c Copy #include <unistd.h> int ft_isspace(char c) { if (c <= 32) return (1); return (0); } void ft_putchar(char c) { write(1, &c, 1); } void r_capitalizer(char *s) { int i = 0; while (s[i]) { // If the character is uppercase, make it lowercase if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32; // Now check for lowercase character and if the next char // is a space character, make it uppercase again if ((s[i] >= 'a' && s[i] <= 'z') && ft_isspace(s[i + 1])) s[i] -= 32; // Now print every char ft_putchar(s[i++]); } } int main(int ac, char **av) { int i = 1; if (ac == 1) ft_putchar('\n'); else { // Loop over all params starting at 1 (we don't want the name of // the executable to be written to the screen) while (i < ac) { r_capitalizer(av[i]); ft_putchar('\n'); i++; } } } sun-brightdesktopmoon --- # paramsum | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum#subject) Subject Copy Assignment name : paramsum Expected files : paramsum.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that displays the number of arguments passed to it, followed by a newline. If there are no arguments, just display a 0 followed by a newline. Example: $>./paramsum 1 2 3 5 7 24 6 $>./paramsum 6 12 24 | cat -e 3$ $>./paramsum | cat -e 0$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum#commented-solution) Commented solution chevron-rightparamsum[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum#paramsum) [Previouslcmchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/lcm) [Nextpgcdchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum#commented-solution) sun-brightdesktopmoon paramsum.c Copy #include <unistd.h> // Simple putnbr function, we don't need negatives since there // will never be less than 0 arguments to a program void ft_putnbr(int nbr) { if (nbr >= 10) ft_putnbr(nbr / 10); char c = nbr % 10 + '0'; write(1, &c, 1); } int main(int ac, char **av) { // Casting argv argument to void to get rid of it // since we'll not use it (void) av; // Writing the number of arguments from argc minus 1 // The first argument counted is the executable name so // not an argument as for this subject ft_putnbr(ac - 1); write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # pgcd | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd#subject) Subject Copy Assignment name : pgcd Expected files : pgcd.c Allowed functions: printf, atoi, malloc, free -------------------------------------------------------------------------------- Write a program that takes two strings representing two strictly positive integers that fit in an int. Display their highest common denominator followed by a newline (It's always a strictly positive integer). If the number of parameters is not 2, display a newline. Examples: $> ./pgcd 42 10 | cat -e 2$ $> ./pgcd 42 12 | cat -e 6$ $> ./pgcd 14 77 | cat -e 7$ $> ./pgcd 17 3 | cat -e 1$ $> ./pgcd | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd#commented-solution) Commented solution [Previousparamsumchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/paramsum) [Nextprint\_hexchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/print_hex) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/pgcd#commented-solution) sun-brightdesktopmoon Copy #include <stdio.h> #include <stdlib.h> int main(int ac, char **av) { if (ac == 3) { // I won't explain the whole thing // but if we take 14 and 77 as input we would // have the following (each iteration separated by ;) // 14; 14; 14; 14; 14; 14; 7 // 77; 63; 49; 35; 21; 7; 7 int number1 = atoi(av[1]); int number2 = atoi(av[2]); if (number1 > 0 && number2 > 0) { while (number1 != number2) { if (number1 > number2) number1 = number1 - number2; else number2 = number2 - number1; } printf("%d", number1); } } printf("\n"); } sun-brightdesktopmoon --- # tab_mult | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult#subject) Subject Copy Assignment name : tab_mult Expected files : tab_mult.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that displays a number's multiplication table. The parameter will always be a strictly positive number that fits in an int, and said number times 9 will also fit in an int. If there are no parameters, the program displays \n. Examples: $>./tab_mult 9 1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81 $>./tab_mult 19 1 x 19 = 19 2 x 19 = 38 3 x 19 = 57 4 x 19 = 76 5 x 19 = 95 6 x 19 = 114 7 x 19 = 133 8 x 19 = 152 9 x 19 = 171 $> $>./tab_mult | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult#commented-solution) Commented solution chevron-righttab\_mult[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult#tab_mult) [Previousstr\_capitalizerchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/str_capitalizer) [NextLevel 4chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4) Last updated 1 year ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-3/tab_mult#commented-solution) sun-brightdesktopmoon tab\_mult.c Copy #include <unistd.h> // Simple atoi since we'll always get a strictly positive integer int ft_atoi(char *s) { int res = 0, i = 0; while (s[i] && s[i] >= 48 && s[i] <= 57) { res *= 10; res += s[i] - 48; i++; } return (res); } // Simple putnbr since we'll always get a strictly positive integer void ft_putnbr(int nbr) { if (nbr >= 10) ft_putnbr(nbr / 10); char c = nbr % 10 + '0'; write(1, &c, 1); } void ft_putstr(char *s) { int i = 0; while (s[i]) write(1, &s[i++], 1); } int main(int ac, char **av) { if (ac != 2) { write(1, "\n", 1); return (0); } int i = 1, n = ft_atoi(av[1]); // Loop from 1 to 9 // and print each line in the format [i x n = i*n] while (i < 10) { ft_putnbr(i); ft_putstr(" x "); ft_putnbr(n); ft_putstr(" = "); ft_putnbr(i * n); write(1, "\n", 1); i++ } } sun-brightdesktopmoon --- # Commented solution | Guide Below we will use my code (Simon) but you can also consult Laura's code, which is a little different from mine on some points. Here are our Github for this project: * [Simon's get\_next\_linearrow-up-right](https://github.com/Laendrun/42/tree/main/get_next_line) triangle-exclamation **And again: Try to do it on your own and only consult the solutions in case of ultimate trouble! And if you want to look at the answers, try to understand what you are doing ;)** I also made this project with the bonus, so you'll have both versions, I'll start with the normal version and you can try to find by yourself how to make the bonuses work. circle-info To make the bonus work I only had to add like 20 - 25 characters in total. The bonus for this project is easily achievable. circle-exclamation I won't be commenting the LIBFT functions, you have your own, I hope you know how they work. chevron-rightget\_next\_line.c[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line.c) get\_next\_line.c Copy #include "get_next_line.h" static char *_fill_line_buffer(int fd, char *left_c, char *buffer); static char *_set_line(char *line); static char *ft_strchr(char *s, int c); char *get_next_line(int fd) { static char *left_c; char *line; char *buffer; buffer = (char *)malloc((BUFFER_SIZE + 1) * sizeof(char)); /* * fd < 0 : this means the file descriptor is invalid * BUFFER_SIZE <= 0 : we'll read BUFFER_SIZE characters at a time, * we can't read 0 or less character * read(fd, 0, 0) < 0 : this check lets us see if the file exists and * that it has some content to read from, or event that the file is * openable to read, maybe the file descriptor is more than 0, but it * was open in 'modify only', that means we can't read it. */ if (fd < 0 || BUFFER_SIZE <= 0 || read(fd, 0, 0) < 0) { free(left_c); free(buffer); left_c = NULL; buffer = NULL; return (NULL); } if (!buffer) return (NULL); line = _fill_line_buffer(fd, left_c, buffer); /* We have to free the buffer variable here since we'll not be using * it later in the function, freeing it prevents memory leaks. */ free(buffer); buffer = NULL; if (!line) return (NULL); left_c = _set_line(line); return (line); } static char *_set_line(char *line_buffer) { char *left_c; ssize_t i; i = 0; /* This loop let's us find the end of the line * either when we encounter a \n or a \0 */ while (line_buffer[i] != '\n' && line_buffer[i] != '\0') i++; /* here we check if the current or next character is a \0 * if this is the case, this means that the line is empty so * we return NULL, this is what the subject asks us, send NULL * if there is no next line */ if (line_buffer[i] == 0 || line_buffer[1] == 0) return (NULL); /* here we take a substring from the end of the line to the end * of the whole line_buffer, that's what's left from our line */ left_c = ft_substr(line_buffer, i + 1, ft_strlen(line_buffer) - i); if (*left_c == 0) { free(left_c); left_c = NULL; } /* don't forget to set the last character to \0 to NUL-terminate * the line */ line_buffer[i + 1] = 0; return (left_c); } static char *_fill_line_buffer(int fd, char *left_c, char *buffer) { /* ssize_t type works the same way as siyze_t type, but it can be * a negative number, something that size_t can't do. * Since most of the system function we'll be using return -1 to * signify errors, it could be useful to be able to store * negative numbers */ ssize_t b_read; char *tmp; b_read = 1; while (b_read > 0) { b_read = read(fd, buffer, BUFFER_SIZE); /* if b_read is -1, it means there was an error reading * the file descriptor, so we free left_c and return NULL. */ if (b_read == -1) { free(left_c); return (NULL); } /* if b_read is 0, this surely means we read the whole * file so there-s no need to stay in the loop */ else if (b_read == 0) /* if we didn't read anything, we can break out of the * loop */ break ; /* don't forget to set the last character of the buffer * to 0 to NUL-terminate the string */ buffer[b_read] = 0; /* there we check if the left_c static char * is empty * because if it's empty, we can't use ft_strjoin on it */ if (!left_c) left_c = ft_strdup(""); tmp = left_c; /* once we set left_c to be empty, if it was NUL * or just that something was left in it from the * last time we called get_next_line * we can join the buffer we just read to left_c */ left_c = ft_strjoin(tmp, buffer); free(tmp); tmp = NULL; /* we search in the buffer we just read if we read * a \n or not * if yes, we can break out of the loop * if not, we go in the loop once again to read more * from the file. */ if (ft_strchr(buffer, '\n')) break ; } /* at the end of this function, we return the left_c string * it will contain everything we read and ensure there's is * either a \0 or a \n within it. */ return (left_c); } static char *ft_strchr(char *s, int c) { unsigned int i; char cc; cc = (char) c; i = 0; while (s[i]) { if (s[i] == cc) return ((char *) &s[i]); i++; } if (s[i] == cc) return ((char *) &s[i]); return (NULL); } chevron-rightget\_next\_line\_utils.c[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line_utils.c) get\_next\_line\_utils.c Copy #include "get_next_line.h" char *ft_strdup(char *s1) { char *dest; unsigned int i; dest = (char *) malloc(ft_strlen(s1) + 1); if (!dest) return (NULL); i = 0; while (s1[i]) { dest[i] = s1[i]; i++; } dest[i] = 0; return (dest); } size_t ft_strlen(char *s) { int i; i = 0; while (s[i]) i++; return (i); } char *ft_substr(char *s, unsigned int start, size_t len) { size_t i; char *str; if (!s) return (NULL); if (start > ft_strlen(s)) return (malloc(1)); if (len > ft_strlen(s + start)) len = ft_strlen(s + start); str = malloc((len + 1) * sizeof(char)); if (!str) return (NULL); i = 0; while (i < len) { str[i] = s[start + i]; i++; } str[i] = 0; return (str); } char *ft_strjoin(char *s1, char *s2) { char *res; res = (char *) malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char)); if (!res) return (NULL); fill_str(res, s1, s2); return (res); } void fill_str(char *res, char *s1, char *s2) { unsigned int i; unsigned int j; i = 0; j = 0; while (s1[j]) res[i++] = s1[j++]; j = 0; while (s2[j]) res[i++] = s2[j++]; res[i] = '\0'; } chevron-rightget\_next\_line.h[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line.h) get\_next\_line.h Copy #ifndef GET_NEXT_LINE_H # define GET_NEXT_LINE_H # ifndef BUFFER_SIZE # define BUFFER_SIZE 42 # endif # include <stdlib.h> # include <unistd.h> # include <fcntl.h> char *get_next_line(int fd); char *ft_strdup(char *s); size_t ft_strlen(char *s); char *ft_substr(char *s, unsigned int start, size_t len); char *ft_strjoin(char *s1, char *s2); void fill_str(char *res, char *s1, char *s2); #endif ### [hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#bonus-part) Bonus part As said before, I made the bonus for this project, so here under I'll put the code for the bonus part. triangle-exclamation I encourage you to really try the bonus by yourself, they are easily achievable as said before. chevron-rightget\_next\_line\_bonus.c[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line_bonus.c) chevron-rightget\_next\_line\_utils\_bonus.c[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line_utils_bonus.c) chevron-rightget\_next\_line\_bonus.h[hashtag](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/commented-solution#get_next_line_bonus.h) [PreviousBuilding the thingchevron-left](https://42-cursus.gitbook.io/guide/1-rank-01/get_next_line/building-the-thing) [Nextso\_longchevron-right](https://42-cursus.gitbook.io/guide/2-rank-02/so_long) Last updated 1 year ago sun-brightdesktopmoon get\_next\_line\_bonus.c Copy #include "get_next_line.h" static char *_fill_line_buffer(int fd, char *left_c, char *buffer); static char *_set_line(char *line); static char *ft_strchr(char *s, int c); char *get_next_line(int fd) { /* There's only a minimal difference to make the bonus * work * It's basically transforming our static char * variable * to an array of char * * as you can see I set the number of elements of the array to * the constant MAX_FD (see get_next_line.h to see what it is) */ static char *left_c[MAX_FD]; char *line; char *buffer; buffer = (char *)malloc((BUFFER_SIZE + 1) * sizeof(char)); if (fd < 0 || BUFFER_SIZE <= 0 || read(fd, 0, 0) < 0) { /* as we changed our static char * to an array * we have to specify wich index we wanna work on * the easier thing to do is to set it to fd */ free(left_c[fd]); free(buffer); left_c[fd] = NULL; buffer = NULL; return (0); } if (!buffer) return (NULL); /* again here, we want to store the left characters in * the array at the index of the fd, so if we have another fd * we won't be overwriting what was left from the other fd */ line = _fill_line_buffer(fd, left_c[fd], buffer); free(buffer); buffer = NULL; if (!line) return (NULL); /* and here again, we have to switch from left_c to left_c[fd] * that's the last thing we have to change, all the other place * we use left_c (in all other functions), we use it as a string * therefore, because we are passing left_c[fd] as parameter * we basically are passing strings as parameter * so no problem there, and nothing to change. */ left_c[fd] = _set_line(line); return (line); } static char *_set_line(char *line_buffer) { char *left_c; ssize_t i; i = 0; while (line_buffer[i] != '\n' && line_buffer[i] != '\0') i++; if (line_buffer[i] == 0 || line_buffer[1] == 0) return (0); left_c = ft_substr(line_buffer, i + 1, ft_strlen(line_buffer) - i); if (*left_c == 0) { free(left_c); left_c = NULL; } line_buffer[i + 1] = 0; return (left_c); } static char *_fill_line_buffer(int fd, char *left_c, char *buffer) { ssize_t b_read; char *tmp; b_read = 1; while (b_read > 0) { b_read = read(fd, buffer, BUFFER_SIZE); if (b_read == -1) { free(left_c); return (0); } else if (b_read == 0) break ; buffer[b_read] = 0; if (!left_c) left_c = ft_strdup(""); tmp = left_c; left_c = ft_strjoin(tmp, buffer); free(tmp); tmp = NULL; if (ft_strchr(buffer, '\n')) break ; } return (left_c); } static char *ft_strchr(char *s, int c) { unsigned int i; char cc; cc = (char) c; i = 0; while (s[i]) { if (s[i] == cc) return ((char *) &s[i]); i++; } if (s[i] == cc) return ((char *) &s[i]); return (NULL); } get\_next\_line\_utils\_bonus.c Copy #include "get_next_line.h" char *ft_strdup(char *s1) { char *dest; unsigned int i; dest = (char *) malloc(ft_strlen(s1) + 1); if (!dest) return (NULL); i = 0; while (s1[i]) { dest[i] = s1[i]; i++; } dest[i] = 0; return (dest); } size_t ft_strlen(char *s) { int i; i = 0; while (s[i]) i++; return (i); } char *ft_substr(char *s, unsigned int start, size_t len) { size_t i; char *str; if (!s) return (NULL); if (start > ft_strlen(s)) return (malloc(1)); if (len > ft_strlen(s + start)) len = ft_strlen(s + start); str = malloc((len + 1) * sizeof(char)); if (!str) return (NULL); i = 0; while (i < len) { str[i] = s[start + i]; i++; } str[i] = 0; return (str); } char *ft_strjoin(char *s1, char *s2) { char *res; res = (char *) malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char)); if (!res) return (NULL); fill_str(res, s1, s2); return (res); } void fill_str(char *res, char *s1, char *s2) { unsigned int i; unsigned int j; i = 0; j = 0; while (s1[j]) res[i++] = s1[j++]; j = 0; while (s2[j]) res[i++] = s2[j++]; res[i] = '\0'; } get\_next\_line\_bonus.h Copy /* * The MAX_FD macro is defined based on the max number of file descriptors * based on my current OS and what I found online (MacOS Ventura 13.0) * (this information is particularly hard to find, or I just don't know * what to search for on Google) */ #ifndef GET_NEXT_LINE_BONUS_H # define GET_NEXT_LINE_BONUS_H # ifndef BUFFER_SIZE # define BUFFER_SIZE 15 # endif # define MAX_FD 10240 # include <stdlib.h> # include <unistd.h> # include <fcntl.h> char *get_next_line(int fd); char *ft_strdup(char *s); size_t ft_strlen(char *s); char *ft_substr(char *s, unsigned int start, size_t len); char *ft_strjoin(char *s1, char *s2); void fill_str(char *res, char *s1, char *s2); #endif sun-brightdesktopmoon --- # Level 2 | Guide Here are the 20 exercises of the level 2 : [alpha\_mirrorchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror) [camel\_to\_snakechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/camel_to_snake) [do\_opchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op) [\*ft\_atoichevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_atoi) [\*ft\_strcmpchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp) [ft\_strcspnchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn) [ft\_strspnchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn) [\*ft\_strdupchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strdup) [ft\_strpbrkchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk) [ft\_strrevchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strrev) [interchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/inter) [last\_wordchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word) [ft\_is\_power\_2chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_is_power_2) [maxchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/max) [print\_bitschevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/print_bits) [reverse\_bitschevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/reverse_bits) [wdmatchchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch) [swap\_bitschevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/swap_bits) [unionchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/union) [snake\_to\_camelchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/snake_to_camel) We already know some of the functions (the ones with \* in front of them). [Previousulstrchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-1/ulstr) [Nextalpha\_mirrorchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror) Last updated 2 years ago sun-brightdesktopmoon sun-brightdesktopmoon --- # ft_strspn | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#subject) Subject Copy Assignment name : ft_strspn Expected files : ft_strspn.c Allowed functions: None --------------------------------------------------------------- Reproduce exactly the behavior of the strspn function (man strspn). The function should be prototyped as follows: size_t ft_strspn(const char *s, const char *accept); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#man-page) Man Page Copy STRSPN(3) (simplified) NAME strspn -- span a string LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <string.h> size_t strspn(const char *s, const char *charset); DESCRIPTION The strcspn() function spans the initial part of the null-terminated string s as long as the characters from s occur in the null-terminated string charset. In other words, it computes the string array index of the first character of s which is not in charset, else the index of the first null character RETURN VALUES The strspn() functions return the number of characters spanned. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#commented-solution) Commented solution chevron-rightft\_strspn.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#ft_strspn.c) [Previousft\_strcspnchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn) [Next\*ft\_strdupchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strdup) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#subject) * [Man Page](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#man-page) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn#commented-solution) sun-brightdesktopmoon Copy #include <stdlib.h> size_t ft_strspn(const char *s, const char *accept) { int i; int j; int check; i = 0; while (s[i]) { j = 0; check = 0; while (accept[j]) { if (s[i] == accept[j]) check = 1; j++; } if (check == 0) return (i); i++; } return (i); } /*#include <stdio.h> int main() { char *s = "hello"; const char *accept = "jfkhpell"; printf("%zu\n", ft_strspn(s, accept)); }*/ sun-brightdesktopmoon --- # alpha_mirror | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror#subject) Subject Copy Assignment name : alpha_mirror Expected files : alpha_mirror.c Allowed functions: write -------------------------------------------------------------------------------- Write a program called alpha_mirror that takes a string and displays this string after replacing each alphabetical character by the opposite alphabetical character, followed by a newline. 'a' becomes 'z', 'Z' becomes 'A' 'd' becomes 'w', 'M' becomes 'N' and so on. Case is not changed. If the number of arguments is not 1, display only a newline. Examples: $>./alpha_mirror "abc" zyx $>./alpha_mirror "My horse is Amazing." | cat -e Nb slihv rh Znzarmt.$ $>./alpha_mirror | cat -e $ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror#commented-solution) Commented solution chevron-rightalpha\_mirror[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror#alpha_mirror) [PreviousLevel 2chevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2) [Nextcamel\_to\_snakechevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/camel_to_snake) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror#commented-solution) sun-brightdesktopmoon alpha\_mirror.c Copy #include <unistd.h> int main(int ac, char *av[]) { int i; if (ac == 2) { i = 0; while (av[1][i]) { if (av[1][i] >= 65 && av[1][i] <= 90) /* we remove the ASCII code of the letter from the ASCII * code of the last upper-case letter, then add the ASCII * code of the first upper-case letter * 90 - 65(A) = 35, 35 + 65 = 90(Z) * 90 - 66(B) = 34, 34 + 65 = 89(Y) */ av[1][i] = 90 - av[1][i] + 65; else if (av[1][i] >= 97 && av[1][i] <= 122) /* we remove the ASCII code of the letter from the ASCII * code of the last lower-case letter, then add the ASCII * code of the first lower-case letter * 122 - 97(a) = 35, 35 + 97 = 122(z) * 122 - 98(b) = 34, 34 + 97 = 121(y) */ av[1][i] = 122 - av[1][i] + 97; /* finally, we can writethe current character to the screen */ write(1, &av[1][i], 1); i++; } } write(1, "\n", 1); } sun-brightdesktopmoon --- # camel_to_snake | Guide Copy Assignment name : camel_to_snake Expected files : camel_to_snake.c Allowed functions: malloc, realloc, write -------------------------------------------------------------------------------- Write a program that takes a single string in lowerCamelCase format and converts it into a string in snake_case format. A lowerCamelCase string is a string where each word begins with a capital letter except for the first one. A snake_case string is a string where each word is in lower case, separated by an underscore "_". Examples: $>./camel_to_snake "hereIsACamelCaseWord" here_is_a_camel_case_word $>./camel_to_snake "helloWorld" | cat -e hello_world$ $>./camel_to_snake | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/camel_to_snake#commented-solution) Commented solution chevron-rightcamel\_to\_snake[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/camel_to_snake#camel_to_snake) [Previousalpha\_mirrorchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/alpha_mirror) [Nextdo\_opchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op) Last updated 2 years ago sun-brightdesktopmoon camel\_to\_snake.c Copy #include <unistd.h> int main(int ac, char *av[]) { int i; if (ac == 2) { i = 0; /* looping over the whole string */ while (av[1][i]) { /* if we encounter an upper-case letter * we have to make it lower-case and write a _ before it */ if (av[1][i] >= 65 && av[1][i] <= 90) { /* here, we change the upper-case letter to its * corresponding lower-case letter */ av[1][i] += 32; /* we write a _ to the screen */ write(1, "_", 1); } /* then we can write the current character, changed or not */ write(1, &av[1][i], 1); i++; } } /* finally we can write the newline */ write(1, "\n", 1); } sun-brightdesktopmoon --- # last_word | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word#subject) Subject Copy Assignment name : last_word Expected files : last_word.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays its last word followed by a \n. A word is a section of string delimited by spaces/tabs or by the start/end of the string. If the number of parameters is not 1, or there are no words, display a newline. Example: $> ./last_word "FOR PONY" | cat -e PONY$ $> ./last_word "this ... is sparta, then again, maybe not" | cat -e not$ $> ./last_word " " | cat -e $ $> ./last_word "a" "b" | cat -e $ $> ./last_word " lorem,ipsum " | cat -e lorem,ipsum$ $> ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word#commented-solution) Commented solution chevron-rightlast\_word.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word#last_word.c) [Previousinterchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/inter) [Nextft\_is\_power\_2chevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_is_power_2) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/last_word#commented-solution) sun-brightdesktopmoon Copy #include <unistd.h> int main (int ac, char **a) { if (ac == 2) { int i = 0; // getting to the end of the string while (a[1][i]) i++; i--; // looping over the whole string backwards // until we found a space while (a[1][i] > 32) i--; i++; // getting back to the end and writing the last word to // the screen while (a[1][i]) { write(1, &a[1][i], 1); i++; } } write (1, "\n", 1); } sun-brightdesktopmoon --- # ft_itoa | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa#subject) Subject Copy Copy Assignment name : ft_itoa Expected files : ft_itoa.c Allowed functions: malloc -------------------------------------------------------------------------------- Write a function that takes an int and converts it to a null-terminated string. The function returns the result in a char array that you must allocate. Your function must be declared as follows: char *ft_itoa(int nbr); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa#commented-solution) Commented solution chevron-rightft\_itoa[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa#ft_itoa) ft\_itoa.c Copy #include "stdlib.h" int ft_count_len(int nbr) { int i; i = 0; if (nbr <= 0) i++; while (nbr != 0) { nbr = nbr / 10; i++; } return (i); } char *ft_itoa(int nbr) { int i; int len; long num; char *str; num = nbr; len = ft_count_len(nbr); str = (char *)malloc((sizeof(char) * (len + 1))); if (!str) return (NULL); str[len] = '\0'; i = len - 1; if (num < 0) { str[0] = '-'; num = -num; } while (num > 9) { str[i] = num % 10 + '0'; num = num / 10; i--; } str[i] = num + '0'; return (str); } [Previousft\_splitchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/fr_split) [Nextft\_list\_foreachchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_list_foreach) Last updated 10 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-4/ft_itoa#commented-solution) sun-brightdesktopmoon sun-brightdesktopmoon --- # do_op | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op#subject) Subject Copy Assignment name : do_op Expected files : *.c, *.h Allowed functions: atoi, printf, write -------------------------------------------------------------------------------- Write a program that takes three strings: - The first and the third one are representations of base-10 signed integers that fit in an int. - The second one is an arithmetic operator chosen from: + - * / % The program must display the result of the requested arithmetic operation, followed by a newline. If the number of parameters is not 3, the program just displays a newline. You can assume the string have no mistakes or extraneous characters. Negative numbers, in input or output, will have one and only one leading '-'. The result of the operation fits in an int. Examples: $> ./do_op "123" "*" 456 | cat -e 56088$ $> ./do_op "9828" "/" 234 | cat -e 42$ $> ./do_op "1" "+" "-43" | cat -e -42$ $> ./do_op | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op#commented-solution) Commented solution chevron-rightdo\_op[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op#do_op) Check this page to understand the `switch` statement : (todo) [Previouscamel\_to\_snakechevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/camel_to_snake) [Next\*ft\_atoichevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_atoi) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/do_op#commented-solution) sun-brightdesktopmoon do\_op.c Copy #include <stdio.h> #include <stdlib.h> int main(int ac, char *av[]) { /* checking the number of arguments */ if (ac == 4) { /* we then switch over the operator (av[2][0]) */ switch(av[2][0]) { /* if the operator is + we simply make an * addition and print the result to the screen */ case '+': printf("%d", atoi(av[1]) + atoi(av[3])); break; /* if the operator is - we simply make a * substraction and print the result to the screen */ case '-': printf("%d", atoi(av[1]) - atoi(av[3])); break; /* if the operator is * we simply make a * multiplication and print the result to the screen */ case '*': printf("%d", atoi(av[1]) * atoi(av[3])); break; /* if the operator is / we simply make a * divisions and print the result to the screen */ case '/': printf("%d", atoi(av[1]) / atoi(av[3])); break; /* if the operator is % we simply make a * modulo and print the result to the screen */ case '%': printf("%d", atoi(av[1]) % atoi(av[3])); break; } } /* finally, we write a newline */ printf("\n"); } sun-brightdesktopmoon --- # ft_strpbrk | Guide This solution has been proposed by Duc Nguyen ([Find his Github link here arrow-up-right](https://github.com/nguyenduc-03/42Student) ) ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#subject) Subject Copy Assignment name : ft_strpbrk Expected files : ft_strpbrk.c Allowed functions: None --------------------------------------------------------------- Reproduce exactly the behavior of the function strpbrk (man strpbrk). The function should be prototyped as follows: char *ft_strpbrk(const char *s1, const char *s2); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#man-page) Man page Copy STRPBRK(3) (simplified) NAME strpbrk –- locate multiple characters in string LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <string.h> char *strpbrk(const char *s, const char *charset); DESCRIPTION The strpbrk() function locates in the null-terminated string s the first occurrence of any character in the string charset and returns a pointer to this character. If no characters from charset occur anywhere in s strpbrk() returns NULL. RETURN VALUES The strpbrk() function return a pointer to the first occurence of any character in the string,if no characters occur anywhere in s, strpbrk() returns NULL. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#commented-solution) Commented solution chevron-rightft\_strpbrk()[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#ft_strpbrk) #### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#explanation-of-char-re-char-s1) Explanation of `char *re = (char *)s1;` In this function, the variable `re` is a temporary pointer that is initially set to the start of the input string `s1`. It is used to track the current position in `s1` as we iterate through it using an index (`i`). Every time we move to the next character in `s1`, we also increment `re`, so that it always points to the same character as `s1[i]`. When a character from `s1` is found in `s2`, `re` is returned. This ensures the function returns a **pointer to the matching character** in `s1`, which is the correct behavior for a `strpbrk`\-like function. [Previous\*ft\_strdupchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strdup) [Nextft\_strrevchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strrev) Last updated 7 months ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#subject) * [Man page](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#man-page) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strpbrk#commented-solution) sun-brightdesktopmoon Copy char *ft_strpbrk(const char *s1, const char *s2) { int i = 0; int j = 0; char *re = (char *)s1; while (s1[i]) { j = 0; while (s2[j]) { if (s1[i] == s2[j]) return re; j++; } i++; re++; } return NULL; } sun-brightdesktopmoon --- # wdmatch | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch#subject) Subject Copy Assignment name : wdmatch Expected files : wdmatch.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes two strings and checks whether it's possible to write the first string with characters from the second string, while respecting the order in which these characters appear in the second string. If it's possible, the program displays the string, followed by a \n, otherwise it simply displays a \n. If the number of arguments is not 2, the program displays a \n. Examples: $>./wdmatch "faya" "fgvvfdxcacpolhyghbreda" | cat -e faya$ $>./wdmatch "faya" "fgvvfdxcacpolhyghbred" | cat -e $ $>./wdmatch "quarante deux" "qfqfsudf arzgsayns tsregfdgs sjytdekuoixq " | cat -e quarante deux$ $>./wdmatch "error" rrerrrfiiljdfxjyuifrrvcoojh | cat -e $ $>./wdmatch | cat -e $ ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch#commented-solution) Commented solution chevron-rightwdmatch.c[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch#wdmatch.c) [Previousreverse\_bitschevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/reverse_bits) [Nextswap\_bitschevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/swap_bits) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch#subject) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/wdmatch#commented-solution) sun-brightdesktopmoon wdmatch.c Copy #include <unistd.h> int main(int ac, char **av) { if (ac == 3) { const char *s1 = av[1]; const char *s2 = av[2]; int len = 0, i = 0; while (s1[len]) len++; // checking all characters of s1 in s2 while (i < len && *s2) { // next line checks if current s1 char is // equal to s2 char, after the comparison is // done, we increment the s2 pointer // even if the condition doesn't match // if the condition match, we increment i to // check for next s1 char if (s1[i] == *s2++) i++; } if (i == len) write(1, s1, len); } write(1, "\n", 1); return (0); } sun-brightdesktopmoon --- # *ft_strcmp | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#subject) Subject Copy Assignment name : ft_strcmp Expected files : ft_strcmp.c Allowed functions: -------------------------------------------------------------------------------- Reproduce the behavior of the function strcmp (man strcmp). Your function must be declared as follows: int ft_strcmp(char *s1, char *s2); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#man-page) Man Page Copy STRCMP(3) (simplified) NAME strcmp -- compare strings SYNOPSIS #include <string.h> int strcmp(const char *s1, const char *s2); DESCRIPTION The strcmp() and strncmp() functions lexicographically compare the null- terminated strings s1 and s2. RETURN VALUES The strcmp() and strncmp() functions return an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2. The comparison is done using unsigned characters, so that ‘\200’ is greater than ‘\0’. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#commented-solution) Commented solution chevron-rightft\_strcmp[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#ft_strcmp) [Previous\*ft\_atoichevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_atoi) [Nextft\_strcspnchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#subject) * [Man Page](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#man-page) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp#commented-solution) sun-brightdesktopmoon Copy int ft_strcmp(char *s1, char *s2) { int i; i = 0; // looping over both string while both of them are equal // and at least one of them is not finished while ((s1[i] || s2[i]) && s1[i] == s2[i]) i++; // when we can't loop anymore, we return the substraction // of the last compared characters in both string, this will // result in either a negative, zero or positive value return (s1[i] - s2[i]); } sun-brightdesktopmoon --- # ft_strcspn | Guide ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#subject) Subject Copy Assignment name : ft_strcspn Expected files : ft_strcspn.c Allowed functions: None --------------------------------------------------------------- Reproduce exactly the behavior of the function strcspn (man strcspn). The function should be prototyped as follows: size_t ft_strcspn(const char *s, const char *reject); ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#man-page) Man Page Copy STRCSPN(3) (simplified) NAME strcspn -- span a string LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <string.h> size_t strcspn(const char *s, const char *charset); DESCRIPTION The strcspn() function spans the initial part of the null-terminated string s as long as the characters from s do not occur in the null- terminated string charset (it spans the complement of the charset). In other words, it computes the string array index of the first character of s which is also in charset, else the index of the first null character. RETURN VALUES The strcspn() functions return the number of characters spanned. ### [hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#commented-solution) Commented solution For this one, I'll give you two different examples, one will be done using indexes in the string `s` and `reject`. And the second example will use pointers directly. chevron-rightIndexes[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#indexes) chevron-rightPointers[hashtag](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#pointers) [Previous\*ft\_strcmpchevron-left](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcmp) [Nextft\_strspnchevron-right](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strspn) Last updated 2 years ago * [Subject](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#subject) * [Man Page](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#man-page) * [Commented solution](https://42-cursus.gitbook.io/guide/exams/exam-rank-02/level-2/ft_strcspn#commented-solution) sun-brightdesktopmoon ft\_strcspn.c Copy // Needed for size_t #include <stdio.h> size_t ft_strcspn(const char *s, const char *reject) { size_t i; size_t j; i = 0; // Looping over the whole string while(s[i++]) { j = 0; // Check the current string char against every char in charset while (reject[j]) { // If character found, return index in current string if (s[i] == reject[j++]) return (i); } } // If we spanned the whole string, return i, in that case the // rejected char found is the NULL-terminating one return (i); } ft\_strcspn.c Copy #include <stdio.h> size_t ft_strcspn(const char *s, const char *reject) { // Save a pointer to the start of s const char *og = s; const char *s2; // Looping over the whole string while (*s++) { // Set s2 to be the start of reject // that way we keep the reject pointer to its original position // Then loop over the whole charset s2 = reject; while (*s2) { // If current string charcter found in charset, return the // number of characters spanned if (*s == *s2++) // Here we make use of the original pointer to calculate // the number of char. spanned return (s - og); } } // Same as above, we use the original pointer to calculate the number // of character spanned return (s - og); } sun-brightdesktopmoon ---