google-site-verification: google61fe8ba583a51912.html
File Seeking in C: Random Access and Navigation in Files

File seeking is a fundamental capability in C that allows programs to move the file position indicator to any location within a file. Unlike sequential access (reading from beginning to end), random access via file seeking enables efficient data retrieval, in-place updates, and complex file structures like databases. For C programmers, mastering file seeking is essential for building applications that work with large files, database systems, and indexed data.

What is File Seeking?

File seeking refers to the ability to reposition the file position indicator (also called the file pointer) to any byte offset within a file. This enables random access—reading or writing at arbitrary locations without having to process all preceding data. The primary functions for file seeking in C are fseek(), ftell(), rewind(), and fgetpos()/fsetpos().

Why File Seeking is Essential in C

  1. Random Access: Read or write data at any position in a file
  2. Efficient Updates: Modify specific records without rewriting entire files
  3. Database Implementation: Create indexed file structures for fast lookups
  4. Large File Processing: Skip to relevant sections without reading everything
  5. File Navigation: Move backward and forward within files
  6. File Size Determination: Quickly find file size without reading contents

Basic File Seeking Functions

#include <stdio.h> #include <stdlib.h> // ============================================================ // BASIC FILE SEEKING FUNCTIONS // ============================================================ int main() { printf("=== Basic File Seeking ===\n\n"); // Create a sample file with sequential data FILE *file = fopen("sample.dat", "w+"); if (file == NULL) { perror("Error creating file"); return 1; } // Write some data for (int i = 1; i <= 10; i++) { fprintf(file, "Line %d: This is line number %d\n", i, i); } // ============================================================ // fseek() - Move to specific position // ftell() - Get current position // rewind() - Go to beginning // ============================================================ printf("File created. Let's navigate:\n\n"); // Get current position (should be at end after writing) long pos = ftell(file); printf("After writing, position: %ld\n", pos); // Go to beginning rewind(file); printf("After rewind(), position: %ld\n", ftell(file)); // Read first line char buffer[100]; fgets(buffer, sizeof(buffer), file); printf("First line: %s", buffer); printf("Position after reading: %ld\n\n", ftell(file)); // Move to position 50 (arbitrary) fseek(file, 50, SEEK_SET); printf("After fseek(file, 50, SEEK_SET):\n"); printf(" Position: %ld\n", ftell(file)); fgets(buffer, sizeof(buffer), file); printf(" Data at that position: %s", buffer); // Move 20 bytes forward from current position fseek(file, 20, SEEK_CUR); printf("\nAfter fseek(file, 20, SEEK_CUR):\n"); printf(" Position: %ld\n", ftell(file)); fgets(buffer, sizeof(buffer), file); printf(" Data: %s", buffer); // Move to end fseek(file, 0, SEEK_END); printf("\nAfter fseek(file, 0, SEEK_END):\n"); printf(" Position: %ld (file size)\n", ftell(file)); fclose(file); return 0; }

The Three Seek Origins

#include <stdio.h> #include <stdlib.h> // ============================================================ // SEEK ORIGINS EXPLAINED // ============================================================ int main() { // Create a test file FILE *file = fopen("seek_test.dat", "w+"); if (file == NULL) return 1; // Write some content fprintf(file, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); printf("=== Seek Origins ===\n"); printf("File content: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); printf("Indices: 0 1 2 3\n"); printf(" 01234567890123456789012345678901\n\n"); // ============================================================ // SEEK_SET - Absolute position from beginning // ============================================================ printf("SEEK_SET - Absolute position from beginning:\n"); fseek(file, 10, SEEK_SET); printf(" Position 10: %c\n", fgetc(file)); fseek(file, 20, SEEK_SET); printf(" Position 20: %c\n", fgetc(file)); fseek(file, 30, SEEK_SET); printf(" Position 30: %c\n\n", fgetc(file)); // ============================================================ // SEEK_CUR - Relative to current position // ============================================================ printf("SEEK_CUR - Relative to current position:\n"); fseek(file, 0, SEEK_SET); // Go to start printf(" At start, reading: "); for (int i = 0; i < 5; i++) { printf("%c", fgetc(file)); } printf("\n"); printf(" Now at position 5\n"); fseek(file, 5, SEEK_CUR); // Skip 5 more printf(" After +5, position %ld: %c\n", ftell(file), fgetc(file)); fseek(file, -3, SEEK_CUR); // Go back 3 printf(" After -3, position %ld: %c\n", ftell(file), fgetc(file)); // ============================================================ // SEEK_END - Relative to end of file // ============================================================ printf("\nSEEK_END - Relative to end of file:\n"); fseek(file, -5, SEEK_END); printf(" -5 from end: %c\n", fgetc(file)); fseek(file, -10, SEEK_END); printf(" -10 from end: %c\n", fgetc(file)); // Get file size fseek(file, 0, SEEK_END); long size = ftell(file); printf(" File size: %ld bytes\n", size); fclose(file); return 0; }

Random Access Record Database

#include <stdio.h> #include <stdlib.h> #include <string.h> // ============================================================ // RANDOM ACCESS RECORD DATABASE // ============================================================ #define MAX_NAME 50 #define MAX_RECORDS 1000 typedef struct { int id; char name[MAX_NAME]; int age; double salary; char active; // 'Y' or 'N' } Employee; const char *DB_FILE = "employees.dat"; // Initialize database file void initDatabase() { FILE *file = fopen(DB_FILE, "wb"); if (file == NULL) return; // Write header with record count (initially 0) int count = 0; fwrite(&count, sizeof(int), 1, file); fclose(file); } // Add employee (appends to end) int addEmployee(Employee *emp) { FILE *file = fopen(DB_FILE, "rb+"); if (file == NULL) return -1; // Read current count int count; fread(&count, sizeof(int), 1, file); // Assign ID emp->id = count + 1; emp->active = 'Y'; // Move to end of file fseek(file, 0, SEEK_END); // Write employee fwrite(emp, sizeof(Employee), 1, file); // Update count at beginning count++; fseek(file, 0, SEEK_SET); fwrite(&count, sizeof(int), 1, file); fclose(file); return emp->id; } // Read employee by ID (random access) Employee* readEmployee(int id) { FILE *file = fopen(DB_FILE, "rb"); if (file == NULL) return NULL; // Read count int count; fread(&count, sizeof(int), 1, file); if (id < 1 || id > count) { fclose(file); return NULL; } // Calculate position: header (4 bytes) + (id-1) * record size long pos = sizeof(int) + (id - 1) * sizeof(Employee); // Seek to that record if (fseek(file, pos, SEEK_SET) != 0) { fclose(file); return NULL; } // Read employee Employee *emp = malloc(sizeof(Employee)); if (fread(emp, sizeof(Employee), 1, file) != 1) { free(emp); fclose(file); return NULL; } fclose(file); if (emp->active != 'Y') { free(emp); return NULL; } return emp; } // Update employee by ID int updateEmployee(int id, Employee *newData) { FILE *file = fopen(DB_FILE, "rb+"); if (file == NULL) return 0; // Read count int count; fread(&count, sizeof(int), 1, file); if (id < 1 || id > count) { fclose(file); return 0; } // Position to record long pos = sizeof(int) + (id - 1) * sizeof(Employee); fseek(file, pos, SEEK_SET); // Preserve ID and active status newData->id = id; newData->active = 'Y'; // Write updated record if (fwrite(newData, sizeof(Employee), 1, file) != 1) { fclose(file); return 0; } fclose(file); return 1; } // Delete employee (soft delete) int deleteEmployee(int id) { FILE *file = fopen(DB_FILE, "rb+"); if (file == NULL) return 0; // Read count int count; fread(&count, sizeof(int), 1, file); if (id < 1 || id > count) { fclose(file); return 0; } // Position to record long pos = sizeof(int) + (id - 1) * sizeof(Employee); fseek(file, pos, SEEK_SET); // Read record Employee emp; fread(&emp, sizeof(Employee), 1, file); // Mark as inactive emp.active = 'N'; // Write back fseek(file, pos, SEEK_SET); fwrite(&emp, sizeof(Employee), 1, file); fclose(file); return 1; } // List all active employees void listAllEmployees() { FILE *file = fopen(DB_FILE, "rb"); if (file == NULL) return; int count; fread(&count, sizeof(int), 1, file); printf("\n=== Employee List ===\n"); printf("%-4s %-20s %-4s %-10s\n", "ID", "Name", "Age", "Salary"); printf("----------------------------------------\n"); for (int i = 0; i < count; i++) { Employee emp; fread(&emp, sizeof(Employee), 1, file); if (emp.active == 'Y') { printf("%-4d %-20s %-4d $%-9.2f\n", emp.id, emp.name, emp.age, emp.salary); } } fclose(file); } int main() { printf("=== Random Access Record Database ===\n\n"); initDatabase(); // Add employees Employee emps[] = { {0, "Alice Johnson", 28, 65000.0, 'Y'}, {0, "Bob Smith", 35, 82000.0, 'Y'}, {0, "Charlie Brown", 42, 95000.0, 'Y'}, {0, "Diana Prince", 31, 71000.0, 'Y'}, {0, "Eve Wilson", 29, 58000.0, 'Y'} }; printf("Adding employees:\n"); for (int i = 0; i < 5; i++) { int id = addEmployee(&emps[i]); printf(" Added %s with ID %d\n", emps[i].name, id); } listAllEmployees(); // Random access reads printf("\n--- Random Access Reads ---\n"); int ids[] = {3, 1, 5, 2}; for (int i = 0; i < 4; i++) { Employee *emp = readEmployee(ids[i]); if (emp) { printf("ID %d: %s, age %d, salary $%.2f\n", emp->id, emp->name, emp->age, emp->salary); free(emp); } } // Update an employee printf("\n--- Update ID 3 ---\n"); Employee updated = {0, "Charlie Brown Jr", 43, 99000.0, 'Y'}; if (updateEmployee(3, &updated)) { printf("Employee 3 updated\n"); } // Delete an employee printf("\n--- Delete ID 2 ---\n"); if (deleteEmployee(2)) { printf("Employee 2 deleted\n"); } listAllEmployees(); return 0; }

Advanced Seeking Techniques

#include <stdio.h> #include <stdlib.h> // ============================================================ // ADVANCED SEEKING TECHNIQUES // ============================================================ // 1. Binary search in sorted file typedef struct { int key; char data[100]; } Record; int binarySearchInFile(const char *filename, int targetKey) { FILE *file = fopen(filename, "rb"); if (file == NULL) return -1; // Get file size fseek(file, 0, SEEK_END); long fileSize = ftell(file); int recordCount = fileSize / sizeof(Record); int left = 0, right = recordCount - 1; Record rec; while (left <= right) { int mid = left + (right - left) / 2; // Seek to middle record fseek(file, mid * sizeof(Record), SEEK_SET); fread(&rec, sizeof(Record), 1, file); if (rec.key == targetKey) { fclose(file); return mid; // Found at index mid } if (rec.key < targetKey) { left = mid + 1; } else { right = mid - 1; } } fclose(file); return -1; // Not found } // 2. Reading file in reverse order void readFileReverse(const char *filename) { FILE *file = fopen(filename, "rb"); if (file == NULL) return; // Go to end fseek(file, 0, SEEK_END); long fileSize = ftell(file); printf("Reading file in reverse:\n"); // Read backwards, one character at a time for (long pos = fileSize - 1; pos >= 0; pos--) { fseek(file, pos, SEEK_SET); int ch = fgetc(file); putchar(ch); } printf("\n"); fclose(file); } // 3. Reading fixed-size chunks with seeking void readChunks(const char *filename, size_t chunkSize) { FILE *file = fopen(filename, "rb"); if (file == NULL) return; // Get file size fseek(file, 0, SEEK_END); long fileSize = ftell(file); rewind(file); int numChunks = (fileSize + chunkSize - 1) / chunkSize; char *buffer = malloc(chunkSize); printf("Reading %d chunks of %zu bytes:\n", numChunks, chunkSize); for (int i = 0; i < numChunks; i++) { // Seek to chunk start fseek(file, i * chunkSize, SEEK_SET); // Read chunk size_t bytesRead = fread(buffer, 1, chunkSize, file); printf("Chunk %d: read %zu bytes at position %ld\n", i, bytesRead, i * chunkSize); } free(buffer); fclose(file); } // 4. Sparse file handling (files with holes) void demonstrateSparseFile() { printf("\n=== Sparse File Handling ===\n"); printf("Sparse files have holes (unallocated regions)\n"); printf("Seeking past end may create holes on some systems\n"); } // 5. Large file support (>2GB) void demonstrateLargeFileSupport() { printf("\n=== Large File Support ===\n"); #ifdef _FILE_OFFSET_BITS printf("_FILE_OFFSET_BITS = %d\n", _FILE_OFFSET_BITS); #endif #ifdef _LARGEFILE_SOURCE printf("_LARGEFILE_SOURCE defined\n"); #endif #ifdef _LARGEFILE64_SOURCE printf("_LARGEFILE64_SOURCE defined\n"); #endif printf("\nFor files >2GB, consider:\n"); printf(" - Use fseeko() and ftello() (off_t type)\n"); printf(" - Define _FILE_OFFSET_BITS=64\n"); printf(" - Use 64-bit file functions (fopen64, fseeko64)\n"); } int main() { printf("=== Advanced Seeking Techniques ===\n"); // Create test file with records FILE *file = fopen("records.dat", "wb"); Record records[] = { {10, "Record 10"}, {20, "Record 20"}, {30, "Record 30"}, {40, "Record 40"}, {50, "Record 50"}, {60, "Record 60"} }; fwrite(records, sizeof(Record), 6, file); fclose(file); // Test binary search int index = binarySearchInFile("records.dat", 40); printf("\nBinary search for key 40: found at index %d\n", index); // Test reverse reading printf("\n"); readFileReverse("sample.dat"); // Use earlier sample file // Test chunk reading printf("\n"); readChunks("sample.dat", 20); demonstrateSparseFile(); demonstrateLargeFileSupport(); return 0; }

File Positioning with fgetpos() and fsetpos()

#include <stdio.h> #include <stdlib.h> // ============================================================ // FGETPOS() AND FSETPOS() - PORTABLE FILE POSITIONING // ============================================================ // fgetpos() and fsetpos() are more portable than ftell/fseek // for very large files and non-Unix systems int main() { printf("=== fgetpos() and fsetpos() ===\n\n"); FILE *file = fopen("positions.dat", "w+"); if (file == NULL) return 1; // Write some data for (int i = 0; i < 10; i++) { fprintf(file, "Line %d\n", i); } fpos_t pos1, pos2, pos3; // Get position after line 3 fseek(file, 0, SEEK_SET); for (int i = 0; i < 3; i++) { fgetc(file); // Skip 3 lines } fgetpos(file, &pos1); printf("Position 1 saved: after line 3\n"); // Get position after line 6 for (int i = 3; i < 6; i++) { fgetc(file); // Skip 3 more lines } fgetpos(file, &pos2); printf("Position 2 saved: after line 6\n"); // Get position at end fseek(file, 0, SEEK_END); fgetpos(file, &pos3); printf("Position 3 saved: at end of file\n"); // Now demonstrate restoring positions char buffer[100]; printf("\nRestoring position 1:\n"); fsetpos(file, &pos1); fgets(buffer, sizeof(buffer), file); printf(" Read: %s", buffer); printf("Restoring position 2:\n"); fsetpos(file, &pos2); fgets(buffer, sizeof(buffer), file); printf(" Read: %s", buffer); printf("Restoring position 3:\n"); fsetpos(file, &pos3); printf(" Position at end: %ld\n", ftell(file)); fclose(file); // Compare fseek/ftell vs fsetpos/fgetpos printf("\nComparison:\n"); printf(" fseek/ftell: Simpler, use long (may be 32-bit)\n"); printf(" fsetpos/fgetpos: More portable, use fpos_t (can be any type)\n"); printf(" fpos_t can represent positions beyond 2GB on all systems\n"); return 0; }

Seeking in Text vs Binary Mode

#include <stdio.h> #include <stdlib.h> // ============================================================ // TEXT MODE VS BINARY MODE SEEKING // ============================================================ int main() { printf("=== Text Mode vs Binary Mode Seeking ===\n\n"); // Create a file with newlines FILE *file = fopen("text_vs_binary.txt", "w"); fprintf(file, "Line 1\n"); fprintf(file, "Line 2\n"); fprintf(file, "Line 3\n"); fprintf(file, "Line 4\n"); fclose(file); // ============================================================ // BINARY MODE - Exact byte positions // ============================================================ printf("Binary mode (exact byte positions):\n"); file = fopen("text_vs_binary.txt", "rb"); fseek(file, 0, SEEK_END); long size = ftell(file); printf(" File size: %ld bytes\n", size); // Show byte positions of newlines rewind(file); long pos = 0; char ch; while ((ch = fgetc(file)) != EOF) { if (ch == '\n') { printf(" Newline at position %ld\n", pos); } pos = ftell(file); } fclose(file); // ============================================================ // TEXT MODE - Positions may be translated // ============================================================ printf("\nText mode (position translation on some systems):\n"); file = fopen("text_vs_binary.txt", "r"); fseek(file, 0, SEEK_END); long textSize = ftell(file); printf(" Text mode size: %ld bytes (may differ on Windows)\n", textSize); // Seek to positions in text mode (may be less predictable) fseek(file, 10, SEEK_SET); printf(" After seek to 10: position %ld\n", ftell(file)); fclose(file); printf("\nNote on Windows:\n"); printf(" - Text mode: \\r\\n translated to \\n\n"); printf(" - Binary mode: \\r\\n preserved as two bytes\n"); printf(" - fseek() with SEEK_END in text mode is not portable\n"); return 0; }

Error Handling in File Seeking

#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> // ============================================================ // ERROR HANDLING IN FILE SEEKING // ============================================================ int safeFseek(FILE *file, long offset, int whence) { // Clear errno before call errno = 0; int result = fseek(file, offset, whence); if (result != 0) { fprintf(stderr, "fseek error: %s\n", strerror(errno)); // Check specific errors if (errno == EBADF) { fprintf(stderr, " Invalid file stream\n"); } else if (errno == EINVAL) { fprintf(stderr, " Invalid whence argument\n"); } else if (errno == ESPIPE) { fprintf(stderr, " Seek not supported on this stream\n"); } else if (errno == EOVERFLOW) { fprintf(stderr, " Offset too large\n"); } } return result; } long safeFtell(FILE *file) { errno = 0; long pos = ftell(file); if (pos == -1L) { fprintf(stderr, "ftell error: %s\n", strerror(errno)); } return pos; } void demonstrateErrors() { printf("=== Error Handling ===\n\n"); // Test 1: Seek on closed file FILE *file = fopen("test.txt", "w"); fclose(file); printf("Seek on closed file:\n"); safeFseek(file, 10, SEEK_SET); // Test 2: Invalid whence file = fopen("test.txt", "w"); printf("\nInvalid whence argument:\n"); safeFseek(file, 10, 999); // Invalid whence // Test 3: Seek beyond valid range printf("\nSeek beyond valid range:\n"); rewind(file); safeFseek(file, -10, SEEK_SET); // Negative position // Test 4: Successful seek printf("\nSuccessful seek:\n"); if (safeFseek(file, 0, SEEK_END) == 0) { long size = safeFtell(file); printf(" File size: %ld\n", size); } fclose(file); } int main() { demonstrateErrors(); return 0; }

Practical Applications

#include <stdio.h> #include <stdlib.h> // ============================================================ // PRACTICAL APPLICATIONS // ============================================================ // 1. Tail command implementation (last n lines) void tail(const char *filename, int n) { FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("Error opening file"); return; } // Go to end fseek(file, 0, SEEK_END); long fileSize = ftell(file); int linesFound = 0; long pos = fileSize - 1; char buffer[1024]; // Scan backwards to find nth newline from end while (pos >= 0 && linesFound < n) { fseek(file, pos, SEEK_SET); int ch = fgetc(file); if (ch == '\n') { linesFound++; } pos--; } // Move to position after the found newline (or start of file) pos += 2; fseek(file, pos, SEEK_SET); // Read and print remaining lines printf("Last %d lines:\n", n); while (fgets(buffer, sizeof(buffer), file)) { printf("%s", buffer); } fclose(file); } // 2. Fast file size without reading long getFileSize(const char *filename) { FILE *file = fopen(filename, "rb"); if (file == NULL) return -1; fseek(file, 0, SEEK_END); long size = ftell(file); fclose(file); return size; } // 3. Check if file is empty int isFileEmpty(const char *filename) { FILE *file = fopen(filename, "rb"); if (file == NULL) return 1; // Treat as empty fseek(file, 0, SEEK_END); int empty = (ftell(file) == 0); fclose(file); return empty; } // 4. Split file into chunks void splitFile(const char *filename, size_t chunkSize) { FILE *src = fopen(filename, "rb"); if (src == NULL) return; long fileSize = getFileSize(filename); int numChunks = (fileSize + chunkSize - 1) / chunkSize; char *buffer = malloc(chunkSize); char outName[256]; for (int i = 0; i < numChunks; i++) { sprintf(outName, "%s.part%d", filename, i); FILE *dst = fopen(outName, "wb"); size_t bytesToRead = (i == numChunks - 1) ? fileSize - i * chunkSize : chunkSize; fread(buffer, 1, bytesToRead, src); fwrite(buffer, 1, bytesToRead, dst); fclose(dst); printf("Created %s (%zu bytes)\n", outName, bytesToRead); } free(buffer); fclose(src); } // 5. Resume download simulation typedef struct { long downloadedBytes; long totalBytes; } DownloadState; void saveDownloadState(DownloadState *state, const char *filename) { FILE *file = fopen(filename, "wb"); if (file) { fwrite(state, sizeof(DownloadState), 1, file); fclose(file); } } DownloadState loadDownloadState(const char *filename) { DownloadState state = {0, 0}; FILE *file = fopen(filename, "rb"); if (file) { fread(&state, sizeof(DownloadState), 1, file); fclose(file); } return state; } void simulateDownload() { const char *stateFile = "download.dat"; DownloadState state = loadDownloadState(stateFile); printf("Resuming download at byte %ld of %ld\n", state.downloadedBytes, state.totalBytes); // Simulate downloading... while (state.downloadedBytes < state.totalBytes) { // Download chunk state.downloadedBytes += 1024; if (state.downloadedBytes > state.totalBytes) { state.downloadedBytes = state.totalBytes; } // Save progress every 10% if (state.downloadedBytes % (state.totalBytes / 10) < 1024) { saveDownloadState(&state, stateFile); printf("Saved progress: %.1f%%\n", (float)state.downloadedBytes / state.totalBytes * 100); } } printf("Download complete!\n"); remove(stateFile); } int main() { printf("=== Practical Applications ===\n\n"); // Create a test file FILE *file = fopen("test.txt", "w"); for (int i = 1; i <= 50; i++) { fprintf(file, "Line %d: This is a test line\n", i); } fclose(file); // Test tail function tail("test.txt", 10); // File size long size = getFileSize("test.txt"); printf("\nFile size: %ld bytes\n", size); // Check if empty printf("File empty: %s\n", isFileEmpty("test.txt") ? "yes" : "no"); // Split file printf("\nSplitting file into chunks:\n"); splitFile("test.txt", 500); return 0; }

Performance Considerations

#include <stdio.h> #include <stdlib.h> #include <time.h> // ============================================================ // PERFORMANCE CONSIDERATIONS // ============================================================ void performanceComparison() { const int SIZE = 100 * 1024 * 1024; // 100 MB const int READS = 10000; // Create large file FILE *file = fopen("large.dat", "wb"); char *buffer = malloc(SIZE); for (int i = 0; i < SIZE; i++) { buffer[i] = rand() % 256; } fwrite(buffer, 1, SIZE, file); fclose(file); free(buffer); printf("=== Performance Considerations ===\n\n"); printf("File size: %d MB\n", SIZE / (1024 * 1024)); printf("Number of reads: %d\n\n", READS); clock_t start, end; // ============================================================ // Sequential access (fast) // ============================================================ file = fopen("large.dat", "rb"); start = clock(); for (int i = 0; i < READS; i++) { // Simulate processing some data fseek(file, i * 1000, SEEK_SET); fgetc(file); } end = clock(); printf("Sequential-like access: %.3f seconds\n", (double)(end - start) / CLOCKS_PER_SEC); fclose(file); // ============================================================ // Random access (slow) // ============================================================ file = fopen("large.dat", "rb"); start = clock(); for (int i = 0; i < READS; i++) { // Random positions long pos = rand() % SIZE; fseek(file, pos, SEEK_SET); fgetc(file); } end = clock(); printf("Random access: %.3f seconds\n", (double)(end - start) / CLOCKS_PER_SEC); fclose(file); // ============================================================ // Impact of seek distance // ============================================================ printf("\nSeek distance impact:\n"); file = fopen("large.dat", "rb"); // Small seeks start = clock(); for (int i = 0; i < READS; i++) { fseek(file, 100, SEEK_CUR); fgetc(file); } end = clock(); printf(" Small seeks (100 bytes): %.3f seconds\n", (double)(end - start) / CLOCKS_PER_SEC); // Large seeks rewind(file); start = clock(); for (int i = 0; i < READS; i++) { fseek(file, 100000, SEEK_CUR); fgetc(file); } end = clock(); printf(" Large seeks (100KB): %.3f seconds\n", (double)(end - start) / CLOCKS_PER_SEC); fclose(file); printf("\nOptimization tips:\n"); printf(" - Minimize seek operations\n"); printf(" - Read larger chunks when possible\n"); printf(" - Sequential access is fastest\n"); printf(" - Consider memory-mapped I/O for random access\n"); printf(" - Buffer frequently accessed data\n"); } int main() { performanceComparison(); return 0; }

Summary Table

FunctionPurposeReturn ValueNotes
fseek(FILE *stream, long offset, int whence)Set file position0 on success, non-zero on errorMost common, uses long offset
ftell(FILE *stream)Get current positionCurrent position or -1L on errorLimited to long range
rewind(FILE *stream)Go to beginningvoidAlso clears error indicators
fgetpos(FILE *stream, fpos_t *pos)Get position0 on success, non-zero on errorMore portable for large files
fsetpos(FILE *stream, fpos_t *pos)Set position0 on success, non-zero on errorUse with positions from fgetpos
fseeko(FILE *stream, off_t offset, int whence)Large file seek0 on success, non-zero on errorUses off_t (64-bit on many systems)
ftello(FILE *stream)Large file tellCurrent position or -1 on errorUses off_t
Seek OriginMeaningExample
SEEK_SETBeginning of filefseek(file, 100, SEEK_SET)
SEEK_CURCurrent positionfseek(file, 20, SEEK_CUR)
SEEK_ENDEnd of filefseek(file, -10, SEEK_END)

Conclusion

File seeking in C provides powerful random access capabilities essential for many applications. Key takeaways:

  1. Three seek origins provide flexibility in positioning:
  • SEEK_SET: Absolute from beginning
  • SEEK_CUR: Relative to current position
  • SEEK_END: Relative to end of file
  1. Common applications include:
  • Database record access
  • File indexing and searching
  • Resumeable downloads
  • File splitting and merging
  • Reading files in reverse
  1. Portability considerations:
  • Text mode vs binary mode affects seek behavior
  • fgetpos/fsetpos are more portable for large files
  • Consider fseeko/ftello for files >2GB
  1. Performance optimization:
  • Sequential access is fastest
  • Minimize seek operations
  • Read larger chunks when possible
  • Buffer frequently accessed data
  1. Error handling is crucial:
  • Always check return values
  • Use errno for detailed error information
  • Handle invalid seeks gracefully

Mastering file seeking transforms file I/O from simple sequential processing to sophisticated random access, enabling efficient data structures and algorithms that work with persistent storage.

Complete C Programming Guide + Compilers Collection


1. C srand() Function – Understanding Seed Initialization

https://macronepal.com/understanding-the-c-srand-function
Explains how srand() initializes the pseudo-random number generator in C by setting a seed value. Using the same seed produces the same sequence, while time(NULL) gives different results each run.


2. C rand() Function Mechanics and Limitations

https://macronepal.com/c-rand-function-mechanics-and-limitations
Explains how rand() generates pseudo-random numbers between 0 and RAND_MAX, its deterministic nature, and limitations for security use cases.


3. C log() Function

https://macronepal.com/c-log-function-2
Covers natural logarithm calculation using <math.h> and its applications.


4. Mastering Date and Time in C

https://macronepal.com/mastering-date-and-time-in-c
Explains <time.h> functions like time(), clock(), difftime(), and struct tm.


5. Mastering time_t Type in C

https://macronepal.com/mastering-the-c-time_t-type-for-time-management
Explains time representation as seconds since Unix epoch and conversion functions.


6. C exp() Function

https://macronepal.com/c-exp-function-mechanics-and-implementation
Explains exponential function exp(x) and its scientific applications.


7. C log() Function (Alternate Guide)

https://macronepal.com/c-log-function
Comparison of log() and log10() with usage examples.


8. C log10() Function

https://macronepal.com/mastering-the-log10-function-in-c
Explains base-10 logarithm for engineering and scientific applications.


9. C tan() Function

https://macronepal.com/understanding-the-c-tan-function
Explains tangent function and radian-based calculations.


10. Random Numbers in C (Secure vs Predictable)

https://macronepal.com/mastering-c-random-numbers-for-secure-and-predictable-applications
Explains difference between rand() and secure randomness methods.


11. Free Online C Compiler

https://macronepal.com/free-online-c-code-compiler-2
Browser-based compiler for testing C programs instantly.


C Functions, Arguments, Parameters & Flow

Mastering Functions in C – Complete Guide

https://macronepal.com/c/mastering-functions-in-c-a-complete-guide/
Covers function structure, modular programming, and real-world usage.


Function Arguments in C

https://macronepal.com/c-function-arguments/
Explains how arguments are passed and used in function calls.


Function Parameters in C

https://macronepal.com/c-function-parameters/
Explains defining inputs for functions and matching them with arguments.


Function Declarations in C

https://macronepal.com/c-function-declarations-syntax-rules-and-best-practices/
Covers prototypes, syntax rules, and best practices.


Function Calls in C

https://macronepal.com/understanding-function-calls-in-c-syntax-mechanics-and-best-practices/
Explains execution flow and parameter handling during function calls.


Void Functions in C

https://macronepal.com/understanding-void-functions-in-c-syntax-patterns-and-best-practices/
Explains functions that do not return values.


Return Values in C

https://macronepal.com/c-return-values-mechanics-types-and-best-practices/
Explains different return types and how functions return results.


Pass-by-Value in C

https://macronepal.com/aws/understanding-pass-by-value-in-c-mechanics-implications-and-best-practices/
Explains how copies of variables are passed into functions.


Pass-by-Reference in C

https://macronepal.com/c/understanding-pass-by-reference-in-c-pointers-semantics-and-safe-practices/
Explains using pointers to modify original variables.


C strstr() Function

https://macronepal.com/aws/c-strstr-function/
Explains substring search inside strings in C.


C Preprocessor & Macros

https://macronepal.com/mastering-c-variadic-macros-for-flexible-debugging/
https://macronepal.com/mastering-the-stdc-macro-in-c/
https://macronepal.com/c-time-macro-mechanics-and-usage/
https://macronepal.com/understanding-the-c-date-macro/
https://macronepal.com/c-file-type/
https://macronepal.com/mastering-c-line-macro-for-debugging-and-diagnostics/
https://macronepal.com/mastering-predefined-macros-in-c/
https://macronepal.com/c-error-directive-mechanics-and-usage/
https://macronepal.com/understanding-the-c-pragma-directive/
https://macronepal.com/c-include-directive/


C Structures, Memory, Scope & Linkage

https://macronepal.com/mastering-structures-in-c/
https://macronepal.com/c-structure-declaration-mechanics-and-usage/
https://macronepal.com/c-structure-initialization-mechanics-and-best-practices/
https://macronepal.com/mastering-c-structure-member-access-for-reliable-data-handling/
https://macronepal.com/c-nested-structures/
https://macronepal.com/mastering-arrays-of-structures-in-c/
https://macronepal.com/c-structure-pointers-mechanics-and-implementation/
https://macronepal.com/understanding-c-structure-parameter-passing-mechanics/
https://macronepal.com/mastering-c-returning-structures-for-efficient-data-flow/
https://macronepal.com/c-self-referential-structures/
https://macronepal.com/mastering-structure-alignment-in-c/
https://macronepal.com/c-structure-padding-mechanics-and-optimization/
https://macronepal.com/understanding-c-flexible-array-members-mechanics-and-usage/
https://macronepal.com/mastering-c-anonymous-structures-for-flattened-data-layouts/
https://macronepal.com/c-unions/
https://macronepal.com/mastering-c-name-mangling-and-symbol-decoration/
https://macronepal.com/c-no-linkage-mechanics-and-scope-isolation/
https://macronepal.com/understanding-c-internal-linkage-mechanics-and-architecture/


C Scope, Storage Classes & Typedef

https://macronepal.com/mastering-function-prototype-scope-in-c/
https://macronepal.com/c-function-scope-mechanics-and-visibility/
https://macronepal.com/understanding-c-file-scope-mechanics-and-architecture/
https://macronepal.com/mastering-c-scope-rules-for-predictable-name-resolution/
https://macronepal.com/c-scope-rules/
https://macronepal.com/mastering-c-register-storage-class-for-historical-context-and-modern-alternatives/
https://macronepal.com/mastering-_thread_local-in-c/
https://macronepal.com/c-extern-storage-class-mechanics-and-usage/
https://macronepal.com/understanding-the-c-static-storage-class-mechanics-and-usage/
https://macronepal.com/c-auto-storage-class/
https://macronepal.com/c-typedef-with-pointers/


Extra Articles

https://macronepal.com/13757-2/
https://macronepal.com/13748-2/
https://macronepal.com/13747-2/
https://macronepal.com/13746-2/
https://macronepal.com/13745-2/
https://macronepal.com/13708-2/
https://macronepal.com/13707-2/
https://macronepal.com/13702-2/


Online Compilers

https://macronepal.com/free-html-online-code-compiler/
https://macronepal.com/free-online-python-code-compiler/
https://macronepal.com/free-online-python2-code-compiler/
https://macronepal.com/free-online-java-code-compiler/
https://macronepal.com/free-online-javascript-code-compiler/
https://macronepal.com/free-online-node-js-code-compiler/
https://macronepal.com/free-online-c-code-compiler/
https://macronepal.com/free-online-c-code-compiler-2/
https://macronepal.com/free-online-c-code-compiler-3/
https://macronepal.com/free-online-php-code-compiler/
https://macronepal.com/free-online-ruby-code-compiler/
https://macronepal.com/free-online-perl-code-compiler/
https://macronepal.com/free-online-lua-code-compiler/
https://macronepal.com/free-online-tcl-code-compiler/
https://macronepal.com/free-online-groovy-code-compiler/
https://macronepal.com/free-online-j-shell-code-compiler/
https://macronepal.com/free-online-haskell-code-compiler/
https://macronepal.com/free-online-scala-code-compiler/
https://macronepal.com/free-online-common-lisp-code-compiler/
https://macronepal.com/free-online-d-code-compiler/
https://macronepal.com/free-online-ada-code-compiler/
https://macronepal.com/free-erlang-code-compiler/
https://macronepal.com/free-online-assembly-code-compiler/

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper