{"id":26202458,"url":"https://github.com/f-corvaro/get_next_line","last_synced_at":"2025-07-03T16:35:58.037Z","repository":{"id":221991250,"uuid":"755963293","full_name":"f-corvaro/GET_NEXT_LINE","owner":"f-corvaro","description":"\"Line-by-Line File Reader\"","archived":false,"fork":false,"pushed_at":"2024-07-27T17:20:36.000Z","size":3702,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-12T03:38:38.753Z","etag":null,"topics":["125","42","42-projects","42roma","42romaluiss","42school","bonus","buffer","educational","file-io","file-reader","getnextline","getnextline42","gnl","gnl-42","gnl42","guide","mandatory"],"latest_commit_sha":null,"homepage":"https://github.com/f-corvaro","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f-corvaro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"f-corvaro","ko_fi":"fcorvaro"}},"created_at":"2024-02-11T15:45:52.000Z","updated_at":"2025-02-19T08:50:23.000Z","dependencies_parsed_at":"2025-03-12T03:37:33.788Z","dependency_job_id":"906878c1-6f7b-445b-a084-53f4d9f839e2","html_url":"https://github.com/f-corvaro/GET_NEXT_LINE","commit_stats":null,"previous_names":["f-corvaro/get_next_line"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/f-corvaro/GET_NEXT_LINE","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f-corvaro%2FGET_NEXT_LINE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f-corvaro%2FGET_NEXT_LINE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f-corvaro%2FGET_NEXT_LINE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f-corvaro%2FGET_NEXT_LINE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f-corvaro","download_url":"https://codeload.github.com/f-corvaro/GET_NEXT_LINE/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f-corvaro%2FGET_NEXT_LINE/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263361222,"owners_count":23454895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["125","42","42-projects","42roma","42romaluiss","42school","bonus","buffer","educational","file-io","file-reader","getnextline","getnextline42","gnl","gnl-42","gnl42","guide","mandatory"],"created_at":"2025-03-12T03:37:17.888Z","updated_at":"2025-07-03T16:35:58.024Z","avatar_url":"https://github.com/f-corvaro.png","language":"C","funding_links":["https://github.com/sponsors/f-corvaro","https://ko-fi.com/fcorvaro"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n\u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg src=\"https://github.com/f-corvaro/GET_NEXT_LINE/blob/main/.extra/gnl.png\"\u003e\u003c/a\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\t\u003cb\u003e\u003ci\u003e\"Line-by-Line File Reader\"\u003c/i\u003e\u003c/b\u003e\u003cbr\u003e\n\u003c/p\u003e\n\u003cp align=\"center\" style=\"text-decoration: none;\"\u003e\n    \u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg alt=\"GitHub code size in bytes\" src=\"https://img.shields.io/github/languages/code-size/f-corvaro/GET_NEXT_LINE?color=blueviolet\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg alt=\"Code language count\" src=\"https://img.shields.io/github/languages/count/f-corvaro/GET_NEXT_LINE?color=yellow\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg alt=\"GitHub top language\" src=\"https://img.shields.io/github/languages/top/f-corvaro/GET_NEXT_LINE?color=blueviolet\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg alt=\"GitHub last commit\" src=\"https://img.shields.io/github/last-commit/f-corvaro/GET_NEXT_LINE?color=yellow\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003eIndex\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n \u003ca href=\"#introduction-to-get_next_line\"\u003eIntroduction to `get_next_line()`\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#folder-structure\"\u003eFolder Structure\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#project-requirements---mandatory-part\"\u003eProject Requirements - Mandatory Part\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#required-files\"\u003eRequired Files\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#function-prototype\"\u003eFunction Prototype\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#allowed-external-functions\"\u003eAllowed External Functions\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#expected-function-behavior\"\u003eExpected Function Behavior\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#compilation-option\"\u003eCompilation Option\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#project-requirements---bonus-part\"\u003eProject Requirements - Bonus Part\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#theoretical-background\"\u003eTheoretical Background\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#string-manipulation\"\u003eString Manipulation\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#data-structures\"\u003eData Structures\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#arrays\"\u003eArrays\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#linked-lists\"\u003eLinked Lists\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#loop-control-and-flow\"\u003eLoop Control and Flow\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#memory-layout-of-c-programs\"\u003eMemory Layout of C Programs\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#detailed-segmentation-of-program-memory\"\u003eDetailed Segmentation of Program Memory\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#understanding-buffer_size-in-memory-management\"\u003eUnderstanding `BUFFER_SIZE` in Memory Management\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#garbage-collection-and-memory-fragmentation\"\u003eGarbage Collection and Memory Fragmentation\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#file-descriptors\"\u003eFile Descriptors\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#standard-file-descriptors\"\u003eStandard File Descriptors\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#error-handling\"\u003eError Handling\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#closing-file-descriptors\"\u003eClosing File Descriptors\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#end-of-line-detection\"\u003eEnd-of-Line Detection\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#static-variables\"\u003eStatic Variables\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#code-optimization\"\u003eCode Optimization\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#into-the-code\"\u003eInto the code\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#evaluation-process\"\u003eEvaluation Process\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#testing-mandatory-part\"\u003eTesting mandatory part\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#testing-bonus-part\"\u003eTesting bonus part\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#testing-with-gnltester\"\u003eTesting with gnlTester\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#moulinette-feedback\"\u003eMoulinette Feedback\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#developed-skills\"\u003eDeveloped Skills\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#references\"\u003eReferences\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#support-and-contributions\"\u003eSupport and Contributions\u003c/a\u003e\u003cbr\u003e\n \u003ca href=\"#author\"\u003eAuthor\u003c/a\u003e\u003cbr\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Introduction to `get_next_line()`\n\n\u003cp align=\"justify\"\u003e\n\nThe `get_next_line()` function stands out as an essential tool for reading lines from a file descriptor without prior knowledge of the line's length. This capability is particularly beneficial for processing large files or those with variable line lengths. Upon execution, it returns a pointer to a buffer that contains the read line, or `NULL` if no more lines are available. This function is a significant addition to our library (LIBFT), enhancing our file handling capabilities.\n\nKey concepts central to this project include understanding static variables and the intricacies of file descriptor management. The use of global variables, the `GET_NEXT_LINE` function itself, and `lseek()` are strictly prohibited to ensure compliance with project guidelines. Moreover, the function is designed to handle errors gracefully, preventing unexpected terminations such as segmentation faults, bus errors, double frees, and other undefined behaviors. It is imperative to manage heap-allocated memory efficiently, ensuring proper release when no longer needed. Through iterative calls, the `get_next_line` function facilitates the sequential reading of a text file associated with a given file descriptor, one line at a time.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Folder Structure\n\n\u003cp align=\"justify\"\u003e\n\n```\n.\n├── 01-get_next_line\n│   ├── get_next_line\n│   │   ├── file.txt\n│   │   ├── file2.txt\n│   │   ├── file3.txt\n│   │   ├── get_next_line_bonus.c\n│   │   ├── get_next_line_bonus.h\n│   │   ├── get_next_line_utils_bonus.c\n│   │   ├── get_next_line_utils.c\n│   │   ├── get_next_line.c\n│   │   └── get_next_line.h\n│   └── README.md\n```\n\n\u003cbr\u003e\n\n## Project Requirements - Mandatory Part\n\n### Required Files \n\n\u003cp align=\"justify\"\u003e\n\nSubmit the following files:\n- `get_next_line.c`: Contains the core logic for the `get_next_line` function.\n- `get_next_line.h`: The header file, which includes the prototype of `get_next_line` and any necessary includes.\n- `get_next_line_utils.c`: This file may contain any helper functions used by your `get_next_line` implementation.\n\n\u003c/p\u003e\n\n### Function Prototype\n\n\u003cp align=\"justify\"\u003e\n\nThe prototype for the `get_next_line` function is as follows:\n- `char *get_next_line(int fd);`\n  - `fd` is the file descriptor from which to read.\n\n\u003c/p\u003e\n\n### Allowed External Functions\n\n\u003cp align=\"justify\"\u003e\n\nYou may only use the following external functions within your project:\n- `free()`\n- `malloc()`\n- `read()`\n\n\u003c/p\u003e\n\n### Expected Function Behavior\n\n\u003cp align=\"justify\"\u003e\n\n- **Return Value**: The function should return the line that has been read. If there is nothing left to read or an error occurs, it should return `NULL`.\n- **Line Termination**: The returned line must include the terminating newline character (`\\n`), except in cases where the end of the file is reached and it does not end with a newline character.\n\n\u003c/p\u003e\n\n### Compilation Option\n\n\u003cp align=\"justify\"\u003e\n\n- Use the `-D BUFFER_SIZE=n` option when compiling your project. This option defines the buffer size for the `read()` function. Your project must compile both with and without this flag. You are free to choose a default buffer size that suits your implementation.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Project Requirements - Bonus Part\n\n\u003cp align=\"justify\"\u003e\n\nThe bonus section of this project introduces an advanced challenge: implementing the `get_next_line()` function with the constraint of using only a single static variable. This requirement pushes the boundaries of efficient memory and state management within your code. For the bonus evaluation, you are expected to submit three specific files: `get_next_line_bonus.c`, `get_next_line_bonus.h`, and `get_next_line_utils_bonus.c`.\n\nIt's crucial to understand that the bonus part will be considered only if the mandatory section of the project is flawlessly completed. \"Flawless\" implies that every aspect of the mandatory requirements has been fully met and functions correctly without any issues. If the mandatory criteria are not entirely satisfied, the bonus submissions will not be reviewed.\n\nA key feature of the bonus `get_next_line()` function is its ability to handle multiple file descriptors (fd) simultaneously. This means that if you're reading from file descriptors 3, 4, and 5, the function should be capable of maintaining the reading sequence for each fd independently, allowing for seamless switching between fds without losing track of their respective reading positions. The choice of `static char *str[4096];` as the static variable is strategic, aligning with the C standard that mandates compilers to support line lengths of at least 4096 characters. This decision, while adhering to the standard, also takes into consideration the capabilities of modern compilers, which typically do not impose a limit on line size, bounded only by the constraints of available memory.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Theoretical Background\n\n\u003cp align=\"justify\"\u003e\n\nThe `get_next_line` project involves several key concepts and system calls that are pivotal for handling file operations in C. It builds upon foundational knowledge from the C piscine and LIBFT project, including:\n\n\u003c/p\u003e\n\n### Data Structures\n\n\u003cp align=\"justify\"\u003e\n\nData structures are an essential component of the `get_next_line` project. They provide a way to organize and store data efficiently, allowing for easy access and manipulation. In the context of `get_next_line`, data structures can be used to store the lines read from a file, ensuring that they are easily accessible for further processing. One commonly used data structure for this purpose is a linked list.\n\n\u003c/p\u003e\n\n#### Arrays\n\n\u003cp align=\"justify\"\u003e\n\nArrays are a fundamental data structure in programming, allowing for the storage of multiple elements of the same type in a contiguous block of memory. In the context of the `get_next_line` project, arrays can be used to store and manipulate characters read from a file. By allocating an array with a fixed size, the function can efficiently read and process chunks of data from the file, ensuring that the lines are correctly extracted. Arrays provide random access to elements, allowing for easy indexing and retrieval of specific characters. Additionally, arrays can be used to store and manage pointers to dynamically allocated memory, ensuring efficient memory management within the `get_next_line` implementation. \n\n\u003c/p\u003e\n\n#### Linked Lists\n\n\u003cp align=\"justify\"\u003e\n\nLinked lists are a valuable data structure for managing and organizing data in the `get_next_line` project. They offer dynamic memory allocation, efficient insertion and deletion operations, and the ability to handle variable-length data. Each node in a linked list represents a line of text, and the nodes are connected through pointers, allowing for easy traversal and manipulation of the data. By utilizing linked lists in the `get_next_line` implementation, the function can effectively manage and process the lines read from the file, ensuring efficient storage and retrieval of the data.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### String Manipulation\n\n\u003cp align=\"justify\"\u003e\n\nString manipulation is a fundamental aspect of the `get_next_line` project. The function is designed to read a file line by line, and string manipulation techniques are essential for processing and extracting the desired data. Functions like `strlen`, `strcpy`, `strcat`, and `strncpy` can be used to manipulate strings, allowing for operations such as finding the length of a string, copying or concatenating strings, and extracting substrings. Additionally, functions like `strchr` and `strstr` can be used to search for specific characters or substrings within a string. Understanding and effectively utilizing these string manipulation functions is crucial for implementing the `get_next_line` function and achieving accurate and efficient file reading functionality.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Loop Control and Flow\n\n\u003cp align=\"justify\"\u003e\n\nLoop control and flow are essential concepts in the `get_next_line` project. The `get_next_line` function needs to read a file line by line, and loop control is used to iterate through the file and extract each line. A common approach is to use a `while` loop that continues until the end of the file is reached or an error occurs. Within the loop, the function reads characters from the file and checks for end-of-line characters to identify the end of each line. Once a line is extracted, it can be processed or stored for further use. Loop control and flow ensure that the `get_next_line` function operates correctly, reading and processing each line in the file until the end is reached or an error occurs.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Memory Layout of C Programs\n\n\u003cp align=\"justify\"\u003e\n\nThe memory architecture of C programs is intricately designed, comprising several segments that each play an important role in the program's lifecycle. This architecture is not just a foundation for efficient program execution but also a bulwark for implementing security measures to safeguard the program's memory space.\n\n\u003c/p\u003e\n\n#### Detailed Segmentation of Program Memory\n\n\u003cp align=\"justify\"\u003e\n\n- **Text Segment**: Also known as the code segment, this area houses the executable instructions of the program. It's typically marked as read-only to prevent tampering with the program's code during execution. Sharing this segment between processes optimizes memory usage, especially for frequently used programs.\n\n- **Initialized Data Segment**: This segment stores global and static variables that have been explicitly initialized by the programmer. Unlike the text segment, this area is writable, enabling runtime modifications of these variables. It's further divided into read-only and read-write sections based on the initialization characteristics.\n\n- **Uninitialized Data Segment (BSS)**: Standing for \"Block Started by Symbol,\" the BSS segment encompasses global and static variables that are either uninitialized or initialized to zero. The operating system zeroes out this segment before the program starts, ensuring a clean slate for these variables.\n\n- **Heap**: The heap area is dedicated to dynamic memory allocation, controlled at runtime through functions like `malloc`. It expands upwards towards higher memory addresses, providing a flexible space for memory allocation as required by the program's execution dynamics.\n\n- **Stack**: In contrast, the stack segment caters to static memory allocation, which includes local variables, function parameters, and return addresses. It grows in the opposite direction of the heap, downwards towards lower memory addresses. The stack is essential for the orderly execution of function calls and returns, with each call generating a new frame on the stack.\n\nUnderstanding the nuanced interplay between these segments is crucial for C programmers. It aids in optimizing memory usage, debugging complex issues, and fortifying programs against common security threats like buffer overflows.\n\n\u003c/p\u003e\n\n#### Understanding `BUFFER_SIZE` in Memory Management\n\n\u003cp align=\"justify\"\u003e\n\nThe `BUFFER_SIZE` parameter plays a pivotal role in memory management, particularly in functions that read from files or streams. It determines the size of the buffer, in bytes, that a program allocates for reading data. This parameter directly influences the efficiency and performance of data handling operations. A larger `BUFFER_SIZE` can reduce the number of read operations required by allowing more data to be read in a single operation, potentially speeding up the process for large files. However, it also means higher memory consumption, which might not be ideal for memory-constrained environments. Conversely, a smaller `BUFFER_SIZE` minimizes memory usage but can lead to increased read operations, which might slow down the program due to the overhead associated with each read call. Balancing the `BUFFER_SIZE` is thus essential for optimizing both performance and memory usage, making it a critical consideration in the design and implementation of efficient C programs.\n\n\u003c/p\u003e\n\n#### Garbage Collection and Memory Fragmentation\n\n\u003cp align=\"justify\"\u003e\n\nUnlike languages with built-in garbage collection mechanisms, C requires manual memory management. Programmers must explicitly allocate and free memory using functions like `malloc` and `free`. This approach necessitates a disciplined management strategy to avoid memory leaks, where unneeded memory is not reclaimed, potentially leading to inefficient memory use and exhaustion of resources. \n\nMemory fragmentation is another challenge in memory management, manifesting in two forms: external and internal fragmentation. External fragmentation occurs when free memory is split into small, scattered blocks, making it difficult to find a contiguous block for new allocations despite having sufficient total free memory. Internal fragmentation happens when allocated memory blocks are larger than necessary, leading to wasted space within those blocks. Addressing these issues involves strategies like memory compaction, using memory pools, or custom allocators to minimize wasted space and improve allocation efficiency. Incorporating an understanding of these concepts is vital for optimizing memory usage and managing the complexities of dynamic memory allocation in C programs.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### File Descriptors\n\n\u003cp align=\"justify\"\u003e\n\nIn the context of the `get_next_line` project, file descriptors play a crucial role in reading data from files. A file descriptor is a unique identifier assigned by the operating system to each open file. It serves as a reference to the file when performing operations like reading or writing. In the `get_next_line` function, file descriptors are used to specify the source from which data should be read. By passing the appropriate file descriptor as a parameter to the `read` function, the function can retrieve data from the specified file. `read` function allows data to be read from a file descriptor into a buffer. The `read` function takes three parameters: the file descriptor, a pointer to the buffer where the data will be stored, and the maximum number of bytes to read. It returns the number of bytes read, which can be zero at the end of the file or -1 in case of an error. By calling the `read` function in a loop, the `get_next_line` function can read the file line by line, processing the data as needed. This allows the `get_next_line` function to handle multiple file descriptors simultaneously, maintaining the reading sequence for each file independently. Understanding file descriptors is essential for efficient file handling and ensuring the correct retrieval of data in the `get_next_line` implementation.\n\n\u003c/p\u003e\n\n#### Standard File Descriptors\n\n\u003cp align=\"justify\"\u003e\n\nThere are three standard file descriptors that are automatically opened when a program starts:\n- **Standard Input (stdin)**: File descriptor 0, used for reading input.\n- **Standard Output (stdout)**: File descriptor 1, used for writing output.\n- **Standard Error (stderr)**: File descriptor 2, used for writing error messages.\n\n\u003c/p\u003e\n\n#### Error Handling\n\n\u003cp align=\"justify\"\u003e\n\nWhen working with file descriptors, it is important to handle errors appropriately. Functions like `open` and `read` return `-1` if an error occurs. Checking the return values of these functions and using `errno` to determine the specific error can help in diagnosing and handling issues effectively. By implementing robust error handling mechanisms, the `get_next_line` function can handle unexpected situations and ensure the reliability and stability of the file reading process.\n\n\u003c/p\u003e\n\n#### Closing File Descriptors\n\n\u003cp align=\"justify\"\u003e\n\nTo prevent resource leaks, it is crucial to close file descriptors when they are no longer needed. The `close` function is used for this purpose. Failing to close file descriptors can lead to a situation where the system runs out of file descriptors, preventing new files from being opened.\n\nBy incorporating these additional details, you gain a more comprehensive understanding of file descriptors, their standard types, error handling, and the importance of proper resource management in the `get_next_line` project.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### End-of-Line Detection\n\n\u003cp align=\"justify\"\u003e\n\nEnd-of-line detection involves identifying the end of a line in a file and extracting the line for further processing. In many text files, lines are terminated by special characters, such as the newline character (`\\n`). The `get_next_line` function needs to detect these end-of-line characters and extract the corresponding line. This can be achieved by reading the file character by character and checking for the presence of end-of-line characters. Once an end-of-line character is detected, the function can extract the line and return it for further processing. End-of-line detection is crucial for accurately reading and processing text files in the `get_next_line` project, ensuring that lines are correctly identified and processed.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Static Variables\n\n\u003cp align=\"justify\"\u003e\n\nStatic variables play a crucial role in the implementation of the `get_next_line` function. A static variable is a variable that retains its value across multiple function calls. In the context of `get_next_line`, static variables are used to keep track of the current position in the file and the buffer that stores the read data. By declaring these variables as static, their values are preserved between function calls, allowing the function to resume reading from where it left off. This is particularly useful when reading large files or when the function is called multiple times to read from different files. Static variables provide a convenient way to maintain state within the function without the need for global variables, ensuring encapsulation and modularity. Understanding the concept of static variables is essential for effectively implementing the `get_next_line` function and achieving efficient and reliable file reading functionality.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Code Optimization\n\n\u003cp align=\"justify\"\u003e\n\nCode optimization is an important consideration in the `get_next_line` project to ensure efficient and performant file reading. Optimizing the code involves identifying and eliminating any unnecessary operations or redundant code that may impact the overall performance. Techniques like loop unrolling, reducing function calls, and minimizing memory allocations can significantly improve the execution speed and resource usage of the `get_next_line` function. Additionally, optimizing the algorithm used for reading and processing the file can lead to significant performance gains. By carefully analyzing the code and making targeted optimizations, the `get_next_line` function can achieve optimal performance and enhance the overall efficiency of the file reading process.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Into the code\n\nThe code for the `get_next_line` project involves several important elements. Firstly, the use of `ssize_t` is highlighted, which is a data type capable of storing either a byte count or an error indication (-1), making it suitable for functions that perform read operations or return sizes. It's specifically designed to accommodate the range of values from -1 to SSIZE_MAX, ensuring that both successful outcomes and errors can be effectively communicated. The `read` function, with the prototype `ssize_t read(int fd, void *buf, size_t count);`, is essential for reading data from a file descriptor into a buffer. It returns the number of bytes read, which can be zero at the end of the file or -1 in case of an error, with `count` specifying the maximum number of bytes to read. This function is crucial for file I/O operations, allowing for direct interaction with files at a low level. Additionally, the `open` function is used to open files for reading, writing, or both, identified by a file descriptor—a small, non-negative integer. The function's syntax, `int open(const char *pathname, int flags);`, includes a pathname to the target file and flags that determine the file access mode. Flags like `O_RDONLY` for read-only access are combined using the `|` operator to specify multiple options. These elements are integral to the project, facilitating direct and efficient manipulation of files within the C programming environment.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Evaluation Process\n\n### Testing mandatory part\n\n\u003cp align=\"justify\"\u003e\n\nTo test the mandatory part of the project, you only need to edit the `get_next_line.c` file and uncomment the main function. The `get_next_line` function will read from the `file.txt` file provided. To compile and run the program, use the following command (replace \"xx\" with the desired buffer size):\n\n```shell\ngcc -Wall -Werror -Wextra -D BUFFER_SIZE=xx get_next_line.c get_next_line_utils.c \u0026\u0026 ./a.out\n```\n\nAdditionally, ensure that the code works without the `-D BUFFER_SIZE=xx` flag, as it must function correctly in both scenarios.\n\n```shell\ngcc -Wall -Werror -Wextra get_next_line.c get_next_line_utils.c \u0026\u0026 ./a.out\n```\n\n### Memory Leak Detection with Valgrind\n\nTo find memory leaks and errors, I used `Valgrind`. Below are the steps for installation and usage:\n\n#### Installation\n\nDepending on your Linux distribution, use one of the following commands to install Valgrind:\n\n```shell\nsudo apt install valgrind  # Ubuntu, Debian, etc.\nsudo yum install valgrind  # RHEL, CentOS, Fedora, etc.\nsudo pacman -Syu valgrind  # Arch, Manjaro, Garuda, etc.\nsudo pkg ins valgrind      # FreeBSD\n```\n\n#### Usage\n\nTo check for memory leaks and errors, use the following Valgrind command:\n\n```shell\nvalgrind --leak-check=full --show-leak-kinds=all --track-origins=yes -s ./a.out\n```\n\n- `--leak-check=full`: Perform a detailed memory leak check.\n- `--show-leak-kinds=all`: Show all kinds of leaks, including definitely lost, indirectly lost, possibly lost, and still reachable.\n- `--track-origins=yes`: Track the origins of uninitialized values.\n- `-s`: Provide a summary of the leak check.\n- ADDITIONAL `--log-file`: Directs Valgrind's output to a specified file. This is useful for preserving extensive output that exceeds terminal capacity, allowing for easier review and analysis.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Testing bonus part\n\n\u003cp align=\"justify\"\u003e\n\nTo test the bonus part of the project, follow these steps:\n\n1. Edit the `get_next_line_bonus.c` file and uncomment the main function.\n2. The `get_next_line` function will read from the `file.txt`, `file2.txt`, and `file3.txt` files provided.\n\nTo compile and run the program, use the following command (replace \"xx\" with the desired buffer size):\n\n```shell\ngcc -Wall -Werror -Wextra -D BUFFER_SIZE=xx get_next_line_bonus.c get_next_line_utils_bonus.c\n```\n\nAdditionally, ensure that the code works without the `-D BUFFER_SIZE=xx` flag, as it must function correctly in both scenarios.\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Testing with gnlTester\n\n\u003cp align=\"justify\"\u003e\n\nI utilized the [gnlTester](https://github.com/Tripouille/gnlTester) developed by [Tripouille](https://github.com/Tripouille) for testing. It's straightforward to use:\n\n1. Navigate to your `get_next_line` directory (e.g., `~/fcorvaro/Desktop/get_next_line`).\n\n2. Clone the gnlTester repository into your `get_next_line` directory using:\n\n  ```shell\n  git clone git@github.com:Tripouille/gnlTester.git\n  ```\n\n3. Change directory to  `gnlTester`\n\n4. Execute the tests with one of the following commands:\n\n  ```shell\n  make m # to run mandatory tests.\n  make b # to run bonus tests.\n  make a # to run mandatory tests and bonus tests.\n  ```\n\nKeep in mind that you can adjust the timeout value in the Makefile for more thorough testing. For a comprehensive evaluation, consider running all tests with Valgrind on Linux (e.g., `valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes -s make m`). Remember, while this tester is a useful tool for validation, it should not be considered the definitive measure of correctness.\n\nThe expected output can be found here: [output.txt](https://github.com/f-corvaro/GET_NEXT_LINE/blob/main/.extra/output.txt)\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n### Moulinette Feedback\n\n\u003cp align=\"justify\"\u003e \n\n\u003ca href=\"https://github.com/f-corvaro/GET_NEXT_LINE\"\u003e\u003cimg src=\"https://github.com/f-corvaro/GET_NEXT_LINE/blob/main/.extra/Moulinette_gnl.png\"\u003e\n\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Developed Skills\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://skillicons.dev\"\u003e\n    \u003cimg src=\"https://skillicons.dev/icons?i=git,c,vim,vscode\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\u003cbr\u003e\n\n## References\n\n- [Understanding Static Variables in C](https://www.geeksforgeeks.org/static-variables-in-c/)\n- [Exploring Memory Layout in C Programs](https://www.geeksforgeeks.org/memory-layout-of-c-program/)\n- [Using Valgrind to Identify Memory Leaks](https://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks)\n\nI used additional references but do not recall their specific sources.\n\n\u003cbr\u003e\n\n## Support and Contributions\n\n\u003cp align=\"center\"\u003e\nIf you find this repository helpful, please consider starring it to show your support. Your support is greatly appreciated!\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://ko-fi.com/fcorvaro\"\u003e\u003cimg width=\"180\" img align=\"center\" src=\"https://github.com/f-corvaro/42.common_core/blob/main/.extra/support-me-ko-fi.svg\"\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/sponsors/f-corvaro\"\u003e\u003cimg width=\"180\" img align=\"center\" src=\"https://github.com/f-corvaro/42.common_core/blob/main/.extra/support-me-github.svg\"\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\n\u003cbr\u003e\n\n## Author\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://profile.intra.42.fr/users/fcorvaro\"\u003e\u003cimg style=\"height:auto;\" src=\"https://avatars.githubusercontent.com/u/102758065?v=4\" width=\"100\" height=\"100\"alt=\"\"\u003e\u003c/a\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"mailto:fcorvaro@student.42roma.it\"\u003e\u003ckbd\u003eEmail\u003c/kbd\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/f-corvaro\"\u003e\u003ckbd\u003eGithub\u003c/kbd\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.linkedin.com/in/f-corvaro/\"\u003e\u003ckbd\u003eLinkedin\u003c/kbd\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\u003ca href=\"https://42born2code.slack.com/team/U050L8XAFLK\"\u003e\u003ckbd\u003eSlack\u003c/kbd\u003e\u003calt=\"\"\u003e\u003c/a\u003e\n\n\u003chr/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff-corvaro%2Fget_next_line","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff-corvaro%2Fget_next_line","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff-corvaro%2Fget_next_line/lists"}