file-handling · intermediate · ~12 min
Locate a suffix of lines and copy it within bounds.
Reproduce tail -n: copy the last N lines of a block of text, found by counting newlines from the end.
Implement int tail_lines(const char *text, int n, char *out, size_t cap) that copies the last n lines of text into out (NUL-terminated), keeping their trailing newlines. If text has n or fewer lines, copy all of it.
text: NUL-terminated text, lines separated by '\n'.n: how many trailing lines to keep (n >= 0).out / cap: destination buffer and its size.Return the number of bytes written to out. Return -1 if text/out is NULL, n < 0, or the result doesn't fit in cap.
text = "l1\nl2\nl3\nl4\nl5\n"
tail_lines(text, 2, out, 128) -> out = "l4\nl5\n"
tail_lines(text, 10, out, 128) -> out = text (fewer lines than n)
tail_lines(text, 1, out, 128) -> out = "l5\n"
n larger than the line count: copy the whole text.cap: -1.max(0, total - n) from the front, then copy the rest. Bound the copy by cap.tail -n is a daily tool; reproducing it means finding the right starting offset by counting newlines from the end.
text: NUL-terminated lines split by '\n'. n: trailing lines to keep. out/cap: buffer and size.
int bytes written to out, or -1 on NULL / overflow / n<0.
Preserve trailing newlines; if there are <= n lines, copy everything.
#include <stddef.h>
int tail_lines(const char *text, int n, char *out, size_t cap) {
/* TODO */
(void)text; (void)n; (void)out; (void)cap;
return -1;
}
Off-by-one when the text doesn't end in a newline. Not bounding the copy by cap.
n larger than the line count → whole text. n=1 → just the last line.
O(text length).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.