Skip to main content

Random Access & Positions

intermediate16 min readLesson 130 of 148

fseek/ftell turn a file into an array: fixed-width records, O(1) seeks, and the update-in-place trap.

A file is an array you can index

Fixed-width records make any record reachable directly:

/* record i of width W: */
fseek(f, (long)i * W, SEEK_SET);   /* SEEK_SET: from the start */
fread(buf, W, 1, f);

ftell reports the current position; SEEK_CUR moves relative, and SEEK_END from the tail (fseek(f, 0, SEEK_END); ftell(f) is the classical file-size idiom โ€” though for real sizes, prefer the OS stat API; this is the stdlib-only version).

"r+" is read AND write โ€” not append

Opening with "r+" allows both directions but does not create the file and does not move the position for you: after writing, the position is where you stopped. "a" (append) always writes at the end but reads nowhere. Modes are contracts โ€” table them once:

| mode | reads | writes | creates | truncates | |---|---|---|---|---| | "r" | โœ“ | โœ— | โœ— | โœ— | | "w" | โœ—* | โœ“ | โœ“ | โœ“ | | "a" | โœ— | โœ“ | โœ“ | โœ— | | "r+" | โœ“ | โœ“ | โœ— | โœ— | | "w+" | โœ“* | โœ“ | โœ“ | โœ“ |

* only after rewinding; "w" truncates on open, destroying existing data โ€” the mode that deletes files when chosen carelessly.

Update in place: the width must match

Overwriting record i via "r+" works only if the new record has exactly the same width โ€” otherwise everything after it shifts and the file is corrupt. Variable-width updates rewrite the tail or use an indirection (slot table) โ€” the reason real databases are complicated.

Now practice

Record I/O GymField-wise binary records with a magic header โ€” write, verify, re-read.1 challenge ยท ยท ~28 min