C fseek function
last modified April 6, 2025
File positioning is crucial for efficient file handling in C programming. The
fseek
function allows precise navigation within files, enabling
random access operations. This tutorial explains fseek
in depth,
covering its parameters, return values, and practical applications. With eight
detailed examples, you'll master file positioning for both text and binary files.
Understanding fseek
enhances your ability to work with large files
and complex data structures.
What Is fseek?
The fseek
function in C repositions the file pointer to a specific
location within a file. It takes three parameters: a FILE
pointer,
a long integer offset, and an origin specifier. The origin can be
SEEK_SET
(start), SEEK_CUR
(current), or
SEEK_END
(end). fseek
returns 0 on success and
non-zero on failure. It works with both text and binary files, though behavior
may differ slightly between them.
Basic fseek Syntax
The function prototype for fseek
is straightforward but powerful.
int fseek(FILE *stream, long offset, int whence);
The stream
parameter is the file pointer obtained from
fopen
. offset
specifies the number of bytes to move,
which can be positive or negative. whence
determines the reference
point for the offset. Always check the return value to ensure the operation
succeeded. Proper error handling prevents unexpected behavior in file operations.
Moving to a Specific Position
This example demonstrates how to jump to a specific position in a file.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { perror("Error opening file"); return 1; } // Move to 10th byte from beginning if (fseek(fp, 10, SEEK_SET)) { perror("Error seeking file"); fclose(fp); return 1; } int ch = fgetc(fp); printf("Character at position 10: %c\n", ch); fclose(fp); return 0; }
Here, fseek
positions the file pointer 10 bytes from the start
(SEEK_SET
). We then read and print the character at that position.
The error handling ensures we catch any issues during file operations. This
technique is useful for accessing specific records in fixed-length files.
Remember to close the file after operations complete.
Seeking from Current Position
Learn how to move relative to the current file position with this example.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { perror("Error opening file"); return 1; } // Read first character int ch1 = fgetc(fp); printf("First character: %c\n", ch1); // Move 5 bytes forward from current position if (fseek(fp, 5, SEEK_CUR)) { perror("Error seeking file"); fclose(fp); return 1; } int ch2 = fgetc(fp); printf("Character after skipping 5: %c\n", ch2); fclose(fp); return 0; }
After reading the first character, fseek
with SEEK_CUR
moves the pointer 5 bytes forward. This relative positioning is valuable when
processing files with variable-length records. The example shows how to skip
ahead from your current location. Always verify the seek operation succeeded
before proceeding with reads or writes.
Seeking from End of File
This example shows how to position the file pointer relative to the end.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { perror("Error opening file"); return 1; } // Move to 5 bytes before end if (fseek(fp, -5, SEEK_END)) { perror("Error seeking file"); fclose(fp); return 1; } printf("Last 5 characters:\n"); int ch; while ((ch = fgetc(fp)) != EOF) { putchar(ch); } fclose(fp); return 0; }
Using SEEK_END
with a negative offset positions the pointer before
the file's end. Here, we read and display the last 5 characters. This technique
is perfect for examining file trailers or footers. Negative offsets are only
valid with SEEK_END
and SEEK_CUR
. The example
includes robust error handling for production-quality code.
Finding File Size with fseek
Combine fseek
and ftell
to determine a file's size.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { perror("Error opening file"); return 1; } // Seek to end if (fseek(fp, 0, SEEK_END)) { perror("Error seeking file"); fclose(fp); return 1; } // Get position (file size) long size = ftell(fp); printf("File size: %ld bytes\n", size); fclose(fp); return 0; }
Moving to the end with fseek
and calling ftell
reveals the file's size in bytes. This method works for both text and binary
files. The size represents the offset from the start to the end position.
Remember that for very large files, you might need fseeko
and
ftello
on some systems. Always reset the pointer if you need to
read the file after checking its size.
Modifying File Content
Use fseek
to update specific parts of a file in read-write mode.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r+"); if (fp == NULL) { perror("Error opening file"); return 1; } // Move to 10th byte if (fseek(fp, 10, SEEK_SET)) { perror("Error seeking file"); fclose(fp); return 1; } // Overwrite character fputc('X', fp); fclose(fp); printf("File modified successfully.\n"); return 0; }
Opening in "r+" mode allows both reading and writing. fseek
positions the pointer at byte 10, and fputc
writes an 'X' at that
location. This approach is ideal for making targeted changes without rewriting
the entire file. Ensure the file exists before opening in "r+" mode. Flushing or
closing the file ensures changes are saved to disk.
Binary File Random Access
Access records in a binary file randomly using fseek
.
#include <stdio.h> struct Record { int id; char name[20]; float value; }; int main() { FILE *fp = fopen("data.bin", "rb+"); if (fp == NULL) { perror("Error opening file"); return 1; } // Read 3rd record (0-based index) if (fseek(fp, 2 * sizeof(struct Record), SEEK_SET)) { perror("Error seeking file"); fclose(fp); return 1; } struct Record rec; fread(&rec, sizeof(struct Record), 1, fp); printf("Record 3: ID=%d, Name=%s, Value=%.2f\n", rec.id, rec.name, rec.value); fclose(fp); return 0; }
This example demonstrates random access in a binary file containing fixed-size
records. fseek
jumps directly to the third record by calculating
the offset. Binary mode ("rb+") ensures accurate positioning and data
representation. The technique is essential for database-like operations. Always
use sizeof
when calculating offsets for portability.
Error Handling with fseek
Proper error handling ensures robust file operations when using fseek
.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); if (fp == NULL) { perror("Error opening file"); return 1; } // Attempt invalid seek if (fseek(fp, -100, SEEK_SET)) { perror("Seek error"); printf("Attempted to seek before file start\n"); } // Attempt valid seek if (fseek(fp, 100, SEEK_SET) == 0) { printf("Seek successful\n"); if (ftell(fp) == 100) { printf("Position verified\n"); } } fclose(fp); return 0; }
This example shows how to handle fseek
errors gracefully.
Attempting to seek before the file start fails, while valid seeks succeed. The
ftell
function verifies the new position. Comprehensive error
checking prevents crashes and data corruption. Always test edge cases when
working with file positioning.
Best Practices for Using fseek
- Check Return Values: Always verify
fseek
returns 0 for success. - Use Binary Mode for Precision: Text mode may alter newlines, affecting positioning.
- Combine with ftell: Use
ftell
to verify positions after seeking. - Handle Large Files Carefully: Consider
fseeko
for files > 2GB on some systems. - Reset Position When Needed: Use
rewind
orfseek
to return to start.
Source
This tutorial has explored the versatile fseek
function through
eight practical examples. From basic positioning to binary file access, you now
have the tools to navigate files efficiently. Mastering fseek
enables sophisticated file handling in your C programs.
Author
List C Standard Library.