Q&A
What is fseek() in C?
Overview
By default, file I/O in C is sequential - each read/write advances an internal file position indicator. fseek() lets you jump that indicator anywhere in the file, so you can read or write at arbitrary positions without processing everything before them. It's the foundation of random-access file handling.
graph LR
A[SEEK_SET: from start] --> P[New position = SEEK base + offset]
B[SEEK_CUR: from current] --> P
C[SEEK_END: from end] --> P
P --> D[Next read/write happens here]
style P fill:#1e1b4b,color:#fff
Signature and Parameters
int fseek(FILE *stream, long offset, int whence);
stream- the open file pointer (fromfopen).offset- number of bytes to move (can be negative).whence- the reference point:SEEK_SET(0): offset from the beginning.SEEK_CUR(1): offset from the current position.SEEK_END(2): offset from the end of the file.
- Returns
0on success, non-zero on error.
Examples
Jump to an absolute position
FILE *fp = fopen("data.bin", "rb");
fseek(fp, 100, SEEK_SET); // go to byte 100 from the start
int x;
fread(&x, sizeof(int), 1, fp); // read the int stored there
Move relative to current position
fseek(fp, -4, SEEK_CUR); // back up 4 bytes (e.g. re-read last int)
Find a file's size (seek to end, then tell)
fseek(fp, 0, SEEK_END); // go to end
long size = ftell(fp); // current position = file size in bytes
rewind(fp); // back to the start (== fseek(fp, 0, SEEK_SET))
printf("File is %ld bytes\n", size);
Companion Functions
| Function | Purpose |
|---|---|
ftell(fp) |
Returns current position (as long) |
rewind(fp) |
Resets position to the start; also clears error flags |
fgetpos / fsetpos |
Position handling for very large files (uses fpos_t) |
fseeko / ftello |
POSIX large-file variants using off_t |
Random-Access Write Example
FILE *fp = fopen("records.bin", "r+b");
struct Record r = { .id = 42, .score = 88 };
fseek(fp, 5 * sizeof(struct Record), SEEK_SET); // jump to record index 5
fwrite(&r, sizeof(struct Record), 1, fp); // overwrite it in place
fclose(fp);
This is how fixed-size-record "databases" support direct access by index.
Important Notes
- Text vs binary streams: On some platforms (notably Windows) text-mode streams translate newlines, so only
SEEK_SETwith offsets returned byftellare guaranteed meaningful. Use binary mode ("rb","r+b") for reliable byte offsets. - Large files:
longmay be too small for files > 2 GB; usefseeko/ftello(POSIX) or_fseeki64(Windows). - Buffering:
fseekdiscards the input buffer and flushes pending output, keeping the position consistent. - Check the return value - seeking can fail (e.g. on non-seekable streams like pipes).
Why This Matters in Interviews
Systems and C interviews use fseek() to test understanding of file position, the three whence constants, and the fseek/ftell/rewind trio. The "get file size with SEEK_END + ftell" idiom is a classic. Mentioning the text-vs-binary mode caveat and large-file variants signals real systems experience.
Common Pitfalls
- Using text mode and getting unreliable offsets (use binary mode).
- Ignoring the return value and seeking on a non-seekable stream (pipe, socket).
longoverflow on files larger than 2 GB.- Forgetting that after writing then reading (or vice versa) on a
"r+"stream, you mustfseek/fflushbetween the two.
References
- C standard library
fseek: https://en.cppreference.com/w/c/io/fseek ftell,rewind: https://en.cppreference.com/w/c/io