{"id":50313059,"url":"https://github.com/simonefelici/get_next_line","last_synced_at":"2026-05-28T22:02:32.205Z","repository":{"id":269993155,"uuid":"909072624","full_name":"SimoneFelici/Get_Next_line","owner":"SimoneFelici","description":"Get the next line of a file every time that is called","archived":false,"fork":false,"pushed_at":"2026-03-15T19:17:05.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-16T06:57:11.211Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SimoneFelici.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-27T17:05:08.000Z","updated_at":"2026-03-15T19:17:09.000Z","dependencies_parsed_at":"2026-03-15T21:06:23.903Z","dependency_job_id":null,"html_url":"https://github.com/SimoneFelici/Get_Next_line","commit_stats":null,"previous_names":["simonefelici/get_next_line"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SimoneFelici/Get_Next_line","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneFelici%2FGet_Next_line","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneFelici%2FGet_Next_line/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneFelici%2FGet_Next_line/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneFelici%2FGet_Next_line/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SimoneFelici","download_url":"https://codeload.github.com/SimoneFelici/Get_Next_line/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimoneFelici%2FGet_Next_line/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33627952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-05-28T22:02:31.964Z","updated_at":"2026-05-28T22:02:32.194Z","avatar_url":"https://github.com/SimoneFelici.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"*This project has been created as part of the 42 curriculum by sfelici.*\n\n# Get Next Line\n\n## Description\n\nGet Next Line is a C function that reads and returns one line at a time from a file descriptor. Each successive call to `get_next_line()` returns the next line until there is nothing left to read, at which point it returns `NULL`. The function works both on regular files and on standard input, and correctly handles any `BUFFER_SIZE` value set at compile time.\n\nThe project introduces a key concept in C programming: **static variables** — variables that persist their value between function calls without being global.\n\nThe bonus part extends the function to handle multiple file descriptors simultaneously, maintaining independent reading state for each one.\n\n## Instructions\n\n### Compilation\n\nThe project must be compiled with the flags `-Wall -Wextra -Werror`. The `BUFFER_SIZE` can be set at compile time using the `-D` flag. If not specified, it defaults to `10`.\n\n**Mandatory:**\n```bash\ncc -Wall -Wextra -Werror -D BUFFER_SIZE=42 get_next_line.c get_next_line_utils.c your_main.c\n```\n\n**Bonus (multi-fd support):**\n```bash\ncc -Wall -Wextra -Werror -D BUFFER_SIZE=42 get_next_line_bonus.c get_next_line_utils_bonus.c your_main.c\n```\n\n### Usage\n\n```c\n#include \"get_next_line.h\"\n#include \u003cfcntl.h\u003e\n\nint main(void)\n{\n    int   fd;\n    char  *line;\n\n    fd = open(\"file.txt\", O_RDONLY);\n    while ((line = get_next_line(fd)) != NULL)\n    {\n        printf(\"%s\", line);\n        free(line);\n    }\n    close(fd);\n    return (0);\n}\n```\n\n### Files\n\n| File | Description |\n|------|-------------|\n| `get_next_line.c` | Core function |\n| `get_next_line_utils.c` | Helper functions (`ft_strlen`, `ft_strchr`, `ft_strjoin`) |\n| `get_next_line.h` | Header file |\n| `get_next_line_bonus.c` | Bonus version with multi-fd support |\n| `get_next_line_utils_bonus.c` | Helper functions for bonus |\n| `get_next_line_bonus.h` | Header file for bonus |\n\n## Algorithm\n\nThe function is split into three stages, each handled by a dedicated static helper:\n\n**1. `reader()` — Fill the stash**\n\nA static variable `stash` acts as a persistent buffer between calls. On each call, `reader()` checks whether `stash` already contains a newline. If it does, no read is needed and the stash is returned as-is. If not, it calls `read()` repeatedly with a buffer of `BUFFER_SIZE` bytes, appending each chunk to the stash via `ft_strjoin()`, until either a `\\n` is found or the file ends.\n\nThis approach ensures we read as little as possible per call — once a newline is found, reading stops immediately, and the remainder stays in the stash for the next call.\n\n**2. `extract_line()` — Extract the current line**\n\nOnce the stash is ready, `extract_line()` allocates and returns a new string containing everything up to and including the first `\\n` (or up to the end of the stash if no `\\n` is present, which handles files without a trailing newline).\n\n**3. `cleaner()` — Trim the stash**\n\nAfter the line is extracted, `cleaner()` shifts the stash forward past the consumed line, keeping only the remaining unread data for the next call. If nothing remains, it frees the stash and sets it to `NULL`.\n\n**Why this design?**\n\nThis three-function split keeps responsibilities clearly separated and makes each part easy to reason about and test. The stash-based approach avoids seeking backwards in the file descriptor (which would require `lseek()`, which is forbidden) and works correctly regardless of the relationship between `BUFFER_SIZE` and the actual line length.\n\n**Bonus — multi-fd support**\n\nThe bonus version replaces the single `static char *stash` with `static char *stash[MAX_FD]`, where `MAX_FD` is defined as `4096` in the header. Each file descriptor uses its own stash slot (`stash[fd]`), so reading states are fully independent. This satisfies the bonus requirement of using only one static variable (an array counts as one variable) while supporting concurrent reading from multiple file descriptors.\n\n## Resources\n\nI don't remember\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonefelici%2Fget_next_line","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonefelici%2Fget_next_line","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonefelici%2Fget_next_line/lists"}