C fgetpos function
last modified April 6, 2025
File position handling is crucial in C programming when working with files. The
fgetpos
function helps track and restore file positions accurately.
This tutorial explains fgetpos
in detail, covering its syntax,
usage, and practical applications. You'll learn how to save and restore file
positions efficiently, ensuring precise file operations in your programs.
What Is fgetpos?
The fgetpos
function in C stores the current file position of a
stream in a fpos_t
object. It takes two parameters: a file pointer
and a pointer to a fpos_t
variable. This function is particularly
useful for large files where ftell
might not provide enough range.
Always check the return value - zero means success, non-zero indicates an error.
Basic fgetpos Usage
This example demonstrates the fundamental usage of fgetpos
to save
a file position.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); fpos_t position; if (fp == NULL) { perror("Error opening file"); return 1; } // Save current position if (fgetpos(fp, &position) { perror("Error getting position"); fclose(fp); return 1; } printf("Position saved successfully\n"); fclose(fp); return 0; }
Here, we open a file and declare a fpos_t
variable to store the
position. fgetpos
saves the current position of the file pointer.
If successful, it returns 0; otherwise, it returns non-zero and sets errno. This
basic example shows how to properly check for errors when using fgetpos
.
Save and Restore Position
This example shows how to save a position and later return to it using
fgetpos
and fsetpos
.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); fpos_t saved_pos; char buffer[100]; if (fp == NULL) { perror("Error opening file"); return 1; } // Read first line fgets(buffer, sizeof(buffer), fp); printf("First line: %s", buffer); // Save position after first line if (fgetpos(fp, &saved_pos)) { perror("Error saving position"); fclose(fp); return 1; } // Read next line fgets(buffer, sizeof(buffer), fp); printf("Second line: %s", buffer); // Return to saved position if (fsetpos(fp, &saved_pos)) { perror("Error restoring position"); fclose(fp); return 1; } // Read again from saved position fgets(buffer, sizeof(buffer), fp); printf("Re-read second line: %s", buffer); fclose(fp); return 0; }
This program demonstrates saving a file position after reading the first line,
then reading the second line, and finally returning to the saved position to
re-read the second line. The fgetpos
/fsetpos
pair is
more reliable than ftell
/fseek
for large files.
Multiple Position Bookmarks
This example shows how to save multiple positions in a file using
fgetpos
.
#include <stdio.h> int main() { FILE *fp = fopen("data.txt", "r"); fpos_t positions[3]; char buffer[100]; int i; if (fp == NULL) { perror("Error opening file"); return 1; } // Save three different positions for (i = 0; i < 3; i++) { fgets(buffer, sizeof(buffer), fp); if (fgetpos(fp, &positions[i])) { perror("Error saving position"); fclose(fp); return 1; } } // Jump between saved positions for (i = 2; i >= 0; i--) { if (fsetpos(fp, &positions[i])) { perror("Error restoring position"); fclose(fp); return 1; } fgets(buffer, sizeof(buffer), fp); printf("Position %d: %s", i, buffer); } fclose(fp); return 0; }
This program saves three different file positions in an array of
fpos_t
structures. It then demonstrates how to jump between these
saved positions in reverse order. This technique is useful when you need to
revisit multiple specific locations in a file.
Binary File Position Handling
This example demonstrates fgetpos
usage with binary files.
#include <stdio.h> int main() { FILE *fp = fopen("data.bin", "rb"); fpos_t position; int value; if (fp == NULL) { perror("Error opening file"); return 1; } // Read first integer fread(&value, sizeof(int), 1, fp); printf("First value: %d\n", value); // Save position if (fgetpos(fp, &position)) { perror("Error saving position"); fclose(fp); return 1; } // Read next integer fread(&value, sizeof(int), 1, fp); printf("Second value: %d\n", value); // Return to saved position if (fsetpos(fp, &position)) { perror("Error restoring position"); fclose(fp); return 1; } // Read again from saved position fread(&value, sizeof(int), 1, fp); printf("Re-read second value: %d\n", value); fclose(fp); return 0; }
This example shows how fgetpos
works with binary files. The program
reads integers from a binary file, saves a position, and demonstrates position
restoration. Binary mode operations often require precise position handling,
making fgetpos
particularly valuable in these scenarios.
Error Handling with fgetpos
This example focuses on proper error handling when using fgetpos
.
#include <stdio.h> #include <errno.h> int main() { FILE *fp = fopen("nonexistent.txt", "r"); fpos_t position; if (fp == NULL) { perror("Error opening file"); return 1; } // Try to get position from invalid file if (fgetpos(fp, &position)) { printf("fgetpos failed with errno: %d\n", errno); perror("Detailed error"); fclose(fp); return 1; } fclose(fp); return 0; }
This example demonstrates how to handle errors when using fgetpos
.
It shows how to check the return value and use errno
and
perror
to get detailed error information. Proper error handling is
essential when working with file positions to ensure program robustness.
Large File Support
This example shows how fgetpos
can handle large files beyond the
range of ftell
.
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp = fopen("largefile.bin", "rb"); fpos_t position; long ftell_result; if (fp == NULL) { perror("Error opening file"); return 1; } // Seek to a large position if (fseek(fp, 2147483647L, SEEK_SET)) { perror("Error seeking in file"); fclose(fp); return 1; } // Save position with fgetpos if (fgetpos(fp, &position)) { perror("Error saving position"); fclose(fp); return 1; } // Compare with ftell ftell_result = ftell(fp); if (ftell_result == -1L) { perror("ftell failed"); } else { printf("ftell result: %ld\n", ftell_result); } printf("Position saved with fgetpos successfully\n"); fclose(fp); return 0; }
This example demonstrates fgetpos
's advantage over ftell
for large files. While ftell
might fail with very large file
positions (beyond LONG_MAX), fgetpos
can handle them correctly.
This makes fgetpos
essential for working with files larger than 2GB.
Random Access with fgetpos
This example shows how to implement random file access using
fgetpos
and fsetpos
.
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp = fopen("data.txt", "r"); fpos_t *positions = NULL; char buffer[100]; int line_count = 0, i; if (fp == NULL) { perror("Error opening file"); return 1; } // First pass: count lines and save positions while (fgets(buffer, sizeof(buffer), fp) { line_count++; } positions = malloc(line_count * sizeof(fpos_t)); if (positions == NULL) { perror("Memory allocation failed"); fclose(fp); return 1; } rewind(fp); for (i = 0; i < line_count; i++) { if (fgetpos(fp, &positions[i])) { perror("Error saving position"); free(positions); fclose(fp); return 1; } fgets(buffer, sizeof(buffer), fp); } // Second pass: access lines in random order for (i = line_count-1; i >= 0; i--) { if (fsetpos(fp, &positions[i])) { perror("Error restoring position"); free(positions); fclose(fp); return 1; } fgets(buffer, sizeof(buffer), fp); printf("Line %d: %s", i+1, buffer); } free(positions); fclose(fp); return 0; }
This program demonstrates advanced random access to file contents. It first scans the file to count lines and save their positions, then accesses them in reverse order. This technique is useful for implementing efficient random access to file contents without loading the entire file into memory.
Best Practices for Using fgetpos
- Always check return values: fgetpos returns 0 on success and non-zero on failure.
- Use for large files: Prefer fgetpos over ftell for files that might exceed 2GB.
- Pair with fsetpos: Saved positions are meant to be used with fsetpos, not directly.
- Consider portability: fpos_t is opaque - don't make assumptions about its structure.
- Combine with error handling: Use perror or strerror to provide meaningful error messages.
Source
This tutorial has explored the fgetpos
function in depth, showing
its importance in file position handling. From basic usage to advanced random
access patterns, fgetpos
provides reliable file position management
for robust file operations in C programs.
Author
List C Standard Library.