get_next_line

get_next_line is a project developed as part of the curriculum at 42 School, aimed at creating a function that reads a file line by line in C. This project serves as a practical exercise in file handling and memory management, enabling students to deepen their understanding of low-level C programming concepts.

GitHub
0
0
0

Last updated

April 07, 2026

get_next_line

get_next_line is a project developed as part of the curriculum at 42 School. It implements a C function that returns a single line read from a file descriptor, one call at a time, with support for configurable read buffer size. The project reinforces file I/O, heap memory management, and static state in C.

Usage

Prerequisites

Clone the repository to your local machine using the following command in the terminal.

sh
git clone https://github.com/milandekruijf/get_next_line.git && cd get_next_line

Compiling

This repository ships the library sources only (no bundled test harness). Compile the mandatory part with your chosen BUFFER_SIZE (required at compile time):

sh
cc -Wall -Wextra -Werror -D BUFFER_SIZE=42 -c get_next_line.c get_next_line_utils.c

For the bonus implementation (multiple file descriptors), use the bonus sources and header instead:

sh
cc -Wall -Wextra -Werror -D BUFFER_SIZE=42 -c get_next_line_bonus.c get_next_line_utils_bonus.c

Compiles with the cc compiler and the flags -Wall, -Wextra, and -Werror. If BUFFER_SIZE is not defined, the headers default it to 1.

Link the resulting object files (.o) from a small main.c or another project that calls get_next_line.

Running

After you add a driver program (for example a main that opens a file or uses STDIN_FILENO and prints each returned line until get_next_line returns NULL), compile and run it—for example:

sh
cc -Wall -Wextra -Werror -D BUFFER_SIZE=42 get_next_line.c get_next_line_utils.c main.c -o gnl
./gnl

Replace main.c with your own program that uses get_next_line.

Debugging

Install Valgrind if needed, then rebuild with debug symbols and run your test binary under Valgrind—for example:

sh
cc -Wall -Wextra -Werror -g3 -D BUFFER_SIZE=42 get_next_line.c get_next_line_utils.c main.c -o gnl
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./gnl

Adjust source file names and arguments if you are testing the bonus build.

Testing

There is no automated test suite in this repository. You can validate behavior with your own driver: repeated calls should return the next line each time; after the last line and end-of-input, get_next_line should return NULL. Try different BUFFER_SIZE values (including 1 and values larger than line length) and, for the bonus, multiple open file descriptors in any order.

Linting

Install Norminette, then run it from the project root on the source and header files—for example:

sh
norminette get_next_line.c get_next_line_utils.c get_next_line.h
norminette get_next_line_bonus.c get_next_line_utils_bonus.c get_next_line_bonus.h

Features

Core behavior

  • Line-oriented reads: Each call to get_next_line(int fd) returns a newly allocated string containing the next line from fd.
  • Newline handling: If a newline is present in the buffered data, the returned line includes that \n character.
  • End of file: After the final line (with or without a trailing newline), the next call returns NULL and internal state is cleared appropriately.
  • Errors: Invalid fd, read errors, invalid BUFFER_SIZE (<= 0), or allocation failure yield NULL.

Mandatory vs bonus

  • Mandatory (get_next_line.c): Uses a single static stash for one logical reading session; switching arbitrarily between many open fd values without consuming each stream fully can mix state (as is typical for the base project scope).
  • Bonus (get_next_line_bonus.c): Keeps separate remainder buffers per file descriptor using a static array indexed by fd, so multiple descriptors can be interleaved.

Utilities

The project includes small helper functions used by the main implementation: string length, character search, join with freeing of the left operand, duplicate, and substring allocation.

Limitations

  • BUFFER_SIZE: Must be defined as a positive integer at compile time for sensible behavior; the default in the headers is 1.
  • Bonus file descriptor range: The bonus static array is sized for file descriptors 01023; descriptors outside that range are not supported by the indexing scheme.

Acknowledgements

  • Valgrind: Memory debugging for leak and error checking while developing the reader.
  • Norminette: Linting against the 42 coding standard.
  • 42: The school that defines the project and learning goals.
  • Codam: The 42 partner campus in the Netherlands where the project was developed.