c
examples
examples.c🔧c
/*
* =============================================================================
* RANDOM ACCESS FILE HANDLING IN C
* Code Examples
* =============================================================================
*
* This file demonstrates random access file operations using fseek, ftell,
* rewind, fgetpos, and fsetpos functions.
*
* Compilation: gcc examples.c -o examples
* =============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/*
* =============================================================================
* EXAMPLE 1: Basic fseek() and ftell()
* =============================================================================
* Demonstrates the fundamental random access operations.
*/
void example_basic_seek_tell(void) {
printf("=== Example 1: Basic fseek() and ftell() ===\n\n");
// Create a test file
FILE *fp = fopen("seek_test.txt", "w");
if (fp == NULL) return;
fprintf(fp, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
fclose(fp);
// Open for reading
fp = fopen("seek_test.txt", "rb");
if (fp == NULL) return;
// Show initial position
printf("Initial position: %ld\n", ftell(fp));
// Read first character
char c = fgetc(fp);
printf("Read '%c', position now: %ld\n", c, ftell(fp));
// Seek to position 10
fseek(fp, 10, SEEK_SET);
c = fgetc(fp);
printf("After SEEK_SET to 10, read '%c', position: %ld\n", c, ftell(fp));
// Seek forward 5 from current
fseek(fp, 5, SEEK_CUR);
c = fgetc(fp);
printf("After SEEK_CUR +5, read '%c', position: %ld\n", c, ftell(fp));
// Seek backward 3 from current
fseek(fp, -3, SEEK_CUR);
c = fgetc(fp);
printf("After SEEK_CUR -3, read '%c', position: %ld\n", c, ftell(fp));
// Seek to end
fseek(fp, 0, SEEK_END);
printf("After SEEK_END, position: %ld (file size)\n", ftell(fp));
// Seek 5 before end
fseek(fp, -5, SEEK_END);
c = fgetc(fp);
printf("After SEEK_END -5, read '%c'\n", c);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 2: Getting File Size
* =============================================================================
* Shows different ways to determine file size.
*/
void example_file_size(void) {
printf("=== Example 2: Getting File Size ===\n\n");
// Create test file with known content
FILE *fp = fopen("size_test.bin", "wb");
if (fp == NULL) return;
int data[100];
for (int i = 0; i < 100; i++) data[i] = i;
fwrite(data, sizeof(int), 100, fp);
fclose(fp);
// Method 1: Using fseek and ftell
fp = fopen("size_test.bin", "rb");
if (fp == NULL) return;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
printf("File size (fseek/ftell method): %ld bytes\n", size);
printf("Expected: %zu bytes\n", sizeof(int) * 100);
printf("Number of integers: %ld\n", size / sizeof(int));
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 3: Using rewind()
* =============================================================================
* Demonstrates going back to the beginning of a file.
*/
void example_rewind(void) {
printf("=== Example 3: Using rewind() ===\n\n");
// Create test file
FILE *fp = fopen("rewind_test.txt", "w");
fprintf(fp, "Line 1: First line\nLine 2: Second line\nLine 3: Third line\n");
fclose(fp);
// Read file multiple times
fp = fopen("rewind_test.txt", "r");
if (fp == NULL) return;
char buffer[100];
// First read
printf("First pass:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf(" %s", buffer);
}
// Rewind and read again
rewind(fp);
printf("\nAfter rewind() - Second pass:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf(" %s", buffer);
}
// Alternative: fseek to beginning
fseek(fp, 0, SEEK_SET);
printf("\nAfter fseek(0, SEEK_SET) - Third pass:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf(" %s", buffer);
}
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 4: fgetpos() and fsetpos()
* =============================================================================
* Using portable position functions for bookmarking.
*/
void example_getpos_setpos(void) {
printf("=== Example 4: fgetpos() and fsetpos() ===\n\n");
// Create test file
FILE *fp = fopen("pos_test.txt", "w");
fprintf(fp, "Position 0: Start\n");
fprintf(fp, "Position 1: Middle section starts here\n");
fprintf(fp, "Position 2: More content\n");
fprintf(fp, "Position 3: End section\n");
fclose(fp);
// Open for reading
fp = fopen("pos_test.txt", "r");
if (fp == NULL) return;
fpos_t bookmark;
char buffer[100];
// Read first line
fgets(buffer, sizeof(buffer), fp);
printf("Read: %s", buffer);
// Save this position
if (fgetpos(fp, &bookmark) != 0) {
perror("fgetpos failed");
fclose(fp);
return;
}
printf("Saved position after first line\n\n");
// Read remaining lines
printf("Continue reading:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf(" %s", buffer);
}
// Restore to bookmarked position
printf("\nRestoring to saved position...\n");
if (fsetpos(fp, &bookmark) != 0) {
perror("fsetpos failed");
fclose(fp);
return;
}
// Read from bookmarked position
printf("Reading from restored position:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf(" %s", buffer);
}
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 5: Random Access with Fixed-Size Records
* =============================================================================
* The most common use case for random access.
*/
void example_fixed_records(void) {
printf("=== Example 5: Fixed-Size Records ===\n\n");
struct Record {
int id;
char name[30];
float score;
};
// Create records
struct Record students[] = {
{1001, "Alice", 95.5},
{1002, "Bob", 87.0},
{1003, "Carol", 92.3},
{1004, "David", 78.9},
{1005, "Eva", 88.7},
{1006, "Frank", 91.2},
{1007, "Grace", 84.5},
{1008, "Henry", 79.8},
{1009, "Ivy", 96.1},
{1010, "Jack", 82.4}
};
int count = sizeof(students) / sizeof(students[0]);
printf("Record size: %zu bytes\n", sizeof(struct Record));
// Write all records
FILE *fp = fopen("students.bin", "wb");
if (fp == NULL) return;
fwrite(students, sizeof(struct Record), count, fp);
fclose(fp);
printf("Wrote %d records\n\n", count);
// Random access: read specific records
fp = fopen("students.bin", "rb");
if (fp == NULL) return;
struct Record rec;
// Read record #3 (0-indexed)
int record_num = 3;
long position = record_num * sizeof(struct Record);
fseek(fp, position, SEEK_SET);
fread(&rec, sizeof(struct Record), 1, fp);
printf("Record #%d: ID=%d, Name=%s, Score=%.1f\n",
record_num, rec.id, rec.name, rec.score);
// Read record #7
record_num = 7;
position = record_num * sizeof(struct Record);
fseek(fp, position, SEEK_SET);
fread(&rec, sizeof(struct Record), 1, fp);
printf("Record #%d: ID=%d, Name=%s, Score=%.1f\n",
record_num, rec.id, rec.name, rec.score);
// Read record #0 (first)
record_num = 0;
fseek(fp, 0, SEEK_SET);
fread(&rec, sizeof(struct Record), 1, fp);
printf("Record #%d: ID=%d, Name=%s, Score=%.1f\n",
record_num, rec.id, rec.name, rec.score);
// Read last record
fseek(fp, -sizeof(struct Record), SEEK_END);
fread(&rec, sizeof(struct Record), 1, fp);
printf("Last record: ID=%d, Name=%s, Score=%.1f\n",
rec.id, rec.name, rec.score);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 6: Updating Records In-Place
* =============================================================================
* Modifying existing records without rewriting the file.
*/
void example_update_in_place(void) {
printf("=== Example 6: Updating Records In-Place ===\n\n");
struct Product {
int code;
char name[30];
float price;
int stock;
};
// Create initial file
struct Product products[] = {
{101, "Widget", 29.99, 100},
{102, "Gadget", 49.99, 50},
{103, "Gizmo", 19.99, 200},
{104, "Doohickey", 9.99, 500},
{105, "Thingamajig", 99.99, 25}
};
FILE *fp = fopen("products.bin", "wb");
fwrite(products, sizeof(struct Product), 5, fp);
fclose(fp);
printf("Original file created.\n\n");
// Open for read/write
fp = fopen("products.bin", "r+b");
if (fp == NULL) return;
// Read and display record #2
struct Product p;
fseek(fp, 2 * sizeof(struct Product), SEEK_SET);
fread(&p, sizeof(struct Product), 1, fp);
printf("Record #2 before update:\n");
printf(" Code: %d, Name: %s, Price: $%.2f, Stock: %d\n\n",
p.code, p.name, p.price, p.stock);
// Modify the record
p.price = 24.99; // New price
p.stock = 150; // New stock
// Seek back to record #2 and update
fseek(fp, 2 * sizeof(struct Product), SEEK_SET);
fwrite(&p, sizeof(struct Product), 1, fp);
printf("Updated record #2.\n\n");
// Verify update
fseek(fp, 2 * sizeof(struct Product), SEEK_SET);
fread(&p, sizeof(struct Product), 1, fp);
printf("Record #2 after update:\n");
printf(" Code: %d, Name: %s, Price: $%.2f, Stock: %d\n",
p.code, p.name, p.price, p.stock);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 7: Simple Database Operations
* =============================================================================
* Implementing CRUD operations using random access.
*/
struct DBRecord {
int id;
char name[50];
char email[50];
int active; // 0 = deleted, 1 = active
};
int db_get_count(const char *filename) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) return 0;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fclose(fp);
return size / sizeof(struct DBRecord);
}
int db_read(const char *filename, int index, struct DBRecord *rec) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) return -1;
fseek(fp, index * sizeof(struct DBRecord), SEEK_SET);
size_t read = fread(rec, sizeof(struct DBRecord), 1, fp);
fclose(fp);
return (read == 1) ? 0 : -1;
}
int db_write(const char *filename, int index, const struct DBRecord *rec) {
FILE *fp = fopen(filename, "r+b");
if (fp == NULL) {
fp = fopen(filename, "wb");
if (fp == NULL) return -1;
}
fseek(fp, index * sizeof(struct DBRecord), SEEK_SET);
size_t written = fwrite(rec, sizeof(struct DBRecord), 1, fp);
fclose(fp);
return (written == 1) ? 0 : -1;
}
int db_append(const char *filename, const struct DBRecord *rec) {
FILE *fp = fopen(filename, "ab");
if (fp == NULL) return -1;
size_t written = fwrite(rec, sizeof(struct DBRecord), 1, fp);
fclose(fp);
return (written == 1) ? 0 : -1;
}
int db_delete(const char *filename, int index) {
struct DBRecord rec;
if (db_read(filename, index, &rec) != 0) return -1;
rec.active = 0; // Mark as deleted
return db_write(filename, index, &rec);
}
int db_find_by_id(const char *filename, int id, struct DBRecord *rec) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) return -1;
int index = 0;
while (fread(rec, sizeof(struct DBRecord), 1, fp) == 1) {
if (rec->active && rec->id == id) {
fclose(fp);
return index;
}
index++;
}
fclose(fp);
return -1;
}
void db_list_all(const char *filename) {
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
printf("No records.\n");
return;
}
struct DBRecord rec;
int index = 0;
printf("%-5s %-6s %-20s %-30s %s\n", "Idx", "ID", "Name", "Email", "Status");
printf("%-5s %-6s %-20s %-30s %s\n", "---", "--", "----", "-----", "------");
while (fread(&rec, sizeof(struct DBRecord), 1, fp) == 1) {
printf("%-5d %-6d %-20s %-30s %s\n",
index, rec.id, rec.name, rec.email,
rec.active ? "Active" : "Deleted");
index++;
}
fclose(fp);
}
void example_database_ops(void) {
printf("=== Example 7: Database Operations ===\n\n");
const char *db_file = "contacts.db";
// Remove old database
remove(db_file);
// Add records
struct DBRecord records[] = {
{1, "Alice Johnson", "alice@example.com", 1},
{2, "Bob Smith", "bob@example.com", 1},
{3, "Carol Williams", "carol@example.com", 1},
{4, "David Brown", "david@example.com", 1}
};
printf("Adding 4 records...\n");
for (int i = 0; i < 4; i++) {
db_append(db_file, &records[i]);
}
printf("\nAll records:\n");
db_list_all(db_file);
// Find by ID
printf("\nFinding ID=3...\n");
struct DBRecord found;
int idx = db_find_by_id(db_file, 3, &found);
if (idx >= 0) {
printf("Found at index %d: %s <%s>\n", idx, found.name, found.email);
}
// Update record
printf("\nUpdating record at index 1...\n");
struct DBRecord updated = {2, "Robert Smith", "robert@newmail.com", 1};
db_write(db_file, 1, &updated);
// Delete record
printf("Deleting record at index 2...\n");
db_delete(db_file, 2);
printf("\nAfter modifications:\n");
db_list_all(db_file);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 8: Swap Two Records
* =============================================================================
* Using random access to swap positions of two records.
*/
void example_swap_records(void) {
printf("=== Example 8: Swap Two Records ===\n\n");
struct Item {
int id;
char name[20];
};
// Create file
struct Item items[] = {
{1, "First"},
{2, "Second"},
{3, "Third"},
{4, "Fourth"},
{5, "Fifth"}
};
FILE *fp = fopen("items.bin", "wb");
fwrite(items, sizeof(struct Item), 5, fp);
fclose(fp);
// Display original
printf("Original order:\n");
fp = fopen("items.bin", "rb");
struct Item item;
for (int i = 0; i < 5; i++) {
fread(&item, sizeof(struct Item), 1, fp);
printf(" [%d] ID: %d, Name: %s\n", i, item.id, item.name);
}
fclose(fp);
// Swap records 1 and 3
printf("\nSwapping records 1 and 3...\n");
fp = fopen("items.bin", "r+b");
struct Item rec1, rec2;
// Read record 1
fseek(fp, 1 * sizeof(struct Item), SEEK_SET);
fread(&rec1, sizeof(struct Item), 1, fp);
// Read record 3
fseek(fp, 3 * sizeof(struct Item), SEEK_SET);
fread(&rec2, sizeof(struct Item), 1, fp);
// Write record 1 at position 3
fseek(fp, 3 * sizeof(struct Item), SEEK_SET);
fwrite(&rec1, sizeof(struct Item), 1, fp);
// Write record 2 at position 1
fseek(fp, 1 * sizeof(struct Item), SEEK_SET);
fwrite(&rec2, sizeof(struct Item), 1, fp);
fclose(fp);
// Display after swap
printf("\nAfter swap:\n");
fp = fopen("items.bin", "rb");
for (int i = 0; i < 5; i++) {
fread(&item, sizeof(struct Item), 1, fp);
printf(" [%d] ID: %d, Name: %s\n", i, item.id, item.name);
}
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 9: Reading File Backwards
* =============================================================================
* Using random access to read a file from end to beginning.
*/
void example_read_backwards(void) {
printf("=== Example 9: Reading File Backwards ===\n\n");
// Create test file
FILE *fp = fopen("backward.bin", "wb");
int numbers[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
fwrite(numbers, sizeof(int), 10, fp);
fclose(fp);
printf("Original order: ");
fp = fopen("backward.bin", "rb");
int num;
while (fread(&num, sizeof(int), 1, fp) == 1) {
printf("%d ", num);
}
printf("\n");
fclose(fp);
// Read backwards
printf("Reverse order: ");
fp = fopen("backward.bin", "rb");
// Get number of integers
fseek(fp, 0, SEEK_END);
long count = ftell(fp) / sizeof(int);
// Read from end to beginning
for (long i = count - 1; i >= 0; i--) {
fseek(fp, i * sizeof(int), SEEK_SET);
fread(&num, sizeof(int), 1, fp);
printf("%d ", num);
}
printf("\n");
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 10: Peek Without Consuming
* =============================================================================
* Reading data without advancing the file position.
*/
void example_peek(void) {
printf("=== Example 10: Peek Without Consuming ===\n\n");
// Create test file
FILE *fp = fopen("peek_test.txt", "w");
fprintf(fp, "First Line\nSecond Line\nThird Line\nFourth Line\n");
fclose(fp);
fp = fopen("peek_test.txt", "r");
char buffer[100];
// Read first line
fgets(buffer, sizeof(buffer), fp);
printf("Read: %s", buffer);
// Peek at next line (read and restore position)
fpos_t pos;
fgetpos(fp, &pos);
fgets(buffer, sizeof(buffer), fp);
printf("Peek: %s", buffer);
fsetpos(fp, &pos); // Restore position
// Read "again" - should be same as peek
fgets(buffer, sizeof(buffer), fp);
printf("Read after peek: %s", buffer);
// Continue reading
fgets(buffer, sizeof(buffer), fp);
printf("Next read: %s", buffer);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 11: Counting Records by Criteria
* =============================================================================
* Scanning file with random access capabilities.
*/
void example_count_by_criteria(void) {
printf("=== Example 11: Counting Records by Criteria ===\n\n");
struct Score {
int student_id;
float score;
char grade;
};
// Create test file
struct Score scores[] = {
{1, 95.0, 'A'},
{2, 82.5, 'B'},
{3, 78.0, 'C'},
{4, 91.0, 'A'},
{5, 65.0, 'D'},
{6, 88.5, 'B'},
{7, 72.0, 'C'},
{8, 98.0, 'A'},
{9, 55.0, 'F'},
{10, 85.0, 'B'}
};
FILE *fp = fopen("scores.bin", "wb");
fwrite(scores, sizeof(struct Score), 10, fp);
fclose(fp);
// Count by grade
fp = fopen("scores.bin", "rb");
int grade_counts[5] = {0}; // A, B, C, D, F
struct Score s;
while (fread(&s, sizeof(struct Score), 1, fp) == 1) {
switch (s.grade) {
case 'A': grade_counts[0]++; break;
case 'B': grade_counts[1]++; break;
case 'C': grade_counts[2]++; break;
case 'D': grade_counts[3]++; break;
case 'F': grade_counts[4]++; break;
}
}
printf("Grade distribution:\n");
printf(" A: %d students\n", grade_counts[0]);
printf(" B: %d students\n", grade_counts[1]);
printf(" C: %d students\n", grade_counts[2]);
printf(" D: %d students\n", grade_counts[3]);
printf(" F: %d students\n", grade_counts[4]);
// Calculate average
rewind(fp); // Go back to beginning
float total = 0;
int count = 0;
while (fread(&s, sizeof(struct Score), 1, fp) == 1) {
total += s.score;
count++;
}
printf("\nClass average: %.2f\n", total / count);
// Find top score (by seeking to each record)
fseek(fp, 0, SEEK_END);
long num_records = ftell(fp) / sizeof(struct Score);
float max_score = 0;
int max_id = 0;
for (long i = 0; i < num_records; i++) {
fseek(fp, i * sizeof(struct Score), SEEK_SET);
fread(&s, sizeof(struct Score), 1, fp);
if (s.score > max_score) {
max_score = s.score;
max_id = s.student_id;
}
}
printf("Top scorer: Student #%d with %.1f\n", max_id, max_score);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* EXAMPLE 12: File Header and Data Sections
* =============================================================================
* Managing file with header containing metadata.
*/
struct FileHeader_Ex12 {
char magic[4];
int version;
int record_count;
time_t created;
time_t modified;
};
struct DataRecord_Ex12 {
int id;
char data[60];
};
void example_header_data_sections(void) {
printf("=== Example 12: File Header and Data Sections ===\n\n");
const char *filename = "headerdata.bin";
// Create file with header
FILE *fp = fopen(filename, "wb");
struct FileHeader_Ex12 header = {
.magic = {'D', 'A', 'T', 'A'},
.version = 1,
.record_count = 3,
.created = time(NULL),
.modified = time(NULL)
};
struct DataRecord_Ex12 records[] = {
{1, "First data record"},
{2, "Second data record"},
{3, "Third data record"}
};
fwrite(&header, sizeof(header), 1, fp);
fwrite(records, sizeof(struct DataRecord_Ex12), 3, fp);
fclose(fp);
printf("Created file with header and %d records.\n\n", header.record_count);
// Read file
fp = fopen(filename, "rb");
// Read and validate header
struct FileHeader_Ex12 read_header;
fread(&read_header, sizeof(read_header), 1, fp);
if (memcmp(read_header.magic, "DATA", 4) != 0) {
printf("Invalid file!\n");
fclose(fp);
return;
}
printf("Header Info:\n");
printf(" Magic: %.4s\n", read_header.magic);
printf(" Version: %d\n", read_header.version);
printf(" Records: %d\n", read_header.record_count);
printf(" Created: %s", ctime(&read_header.created));
// Calculate data offset
long data_offset = sizeof(struct FileHeader_Ex12);
printf("\nData section starts at offset: %ld\n\n", data_offset);
// Read specific record (record #1)
long record_offset = data_offset + 1 * sizeof(struct DataRecord_Ex12);
fseek(fp, record_offset, SEEK_SET);
struct DataRecord_Ex12 rec;
fread(&rec, sizeof(rec), 1, fp);
printf("Record #1: ID=%d, Data='%s'\n", rec.id, rec.data);
fclose(fp);
printf("\n");
}
/*
* =============================================================================
* MAIN FUNCTION - Run All Examples
* =============================================================================
*/
int main(void) {
printf("\n");
printf("╔═══════════════════════════════════════════════════════════════╗\n");
printf("║ RANDOM ACCESS FILE HANDLING - CODE EXAMPLES ║\n");
printf("╚═══════════════════════════════════════════════════════════════╝\n\n");
example_basic_seek_tell();
example_file_size();
example_rewind();
example_getpos_setpos();
example_fixed_records();
example_update_in_place();
example_database_ops();
example_swap_records();
example_read_backwards();
example_peek();
example_count_by_criteria();
example_header_data_sections();
printf("╔═══════════════════════════════════════════════════════════════╗\n");
printf("║ ALL EXAMPLES COMPLETED ║\n");
printf("╚═══════════════════════════════════════════════════════════════╝\n\n");
return 0;
}