file-handling · beginner · ~20 min
Safe bounded copy with a running pointer + remaining-capacity counter.
Concatenate several byte buffers into one fixed-size output, truncating safely so you never overrun — the bounded-copy pattern behind cat.
Implement size_t cat_buffers(const char **bufs, const size_t *lens, size_t n, char *out, size_t cap) that appends bufs[0], bufs[1], ..., bufs[n-1] into out, writing at most cap bytes total including the trailing NUL.
bufs: array of n source buffers; lens[i] is the length of bufs[i].n: number of buffers (may be 0).out / cap: destination buffer and its capacity (cap >= 1).Return the number of bytes written, not counting the trailing NUL. out is always NUL-terminated. If the inputs would exceed cap, copy as much as fits and stop (safe truncation).
bufs={"hello, ","world","!"}, lens={7,5,1}, cap=32 -> 13, out="hello, world!"
same inputs, cap=6 -> 5, out="hello"
same inputs, cap=1 -> 0, out=""
n=0, cap=8 -> 0, out=""
cap == 1: only the NUL fits, so 0 bytes are written.n == 0: just NUL-terminate out, return 0.cap: truncate.malloc. Reserve one byte for the NUL before copying.cat looks trivial but the careful concatenation with bounds checking is a model for all 'copy bytes into a fixed buffer' patterns — the place where strncpy footguns kill projects.
bufs[n] sources with lengths lens[n]; out/cap destination (cap >= 1).
Bytes written excluding the NUL; out is always NUL-terminated.
No malloc; truncate to fit cap, reserving a byte for the NUL.
#include <stddef.h>
size_t cat_buffers(const char **bufs, const size_t *lens, size_t n, char *out, size_t cap) { /* TODO */ return 0; }
Forgetting the NUL byte in the budget; using strcat (re-scans every call — O(n^2)); writing one byte past the buffer.
cap == 1 (only the NUL fits). n == 0 (just NUL out). One buffer larger than cap (truncate).
O(total bytes).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.