c

exercises

exercises.c🔧
/*
 * =============================================================================
 *                         BINARY FILES IN C
 *                         Practice Exercises
 * =============================================================================
 * 
 * Complete the following exercises to practice binary file operations.
 * Each exercise builds upon concepts from basic to advanced.
 * 
 * Compilation: gcc exercises.c -o exercises
 * =============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>

/*
 * =============================================================================
 * EXERCISE 1: Write and Read Single Integer
 * =============================================================================
 * 
 * Task: Write a single integer to a binary file and read it back.
 * 
 * Requirements:
 * - Write integer 123456 to "number.bin"
 * - Read it back and verify it matches
 * - Print the file size (should be 4 bytes on most systems)
 */
void exercise1(void) {
    printf("Exercise 1: Write and Read Single Integer\n");
    printf("------------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 2: Store Array of Doubles
 * =============================================================================
 * 
 * Task: Write an array of 100 doubles to binary file and read them back.
 * 
 * Requirements:
 * - Create array of 100 doubles with values 0.0, 0.1, 0.2, ..., 9.9
 * - Write to "doubles.bin"
 * - Read back and verify first 10 and last 10 values
 * - Compare file size with sizeof(double) * 100
 */
void exercise2(void) {
    printf("Exercise 2: Store Array of Doubles\n");
    printf("-----------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 3: Structure Serialization
 * =============================================================================
 * 
 * Task: Create a Book structure and store multiple books in binary file.
 * 
 * Requirements:
 * - Define struct Book with: isbn (char[14]), title (char[50]), 
 *   author (char[30]), year (int), price (float)
 * - Create at least 5 book records
 * - Write count followed by all records to "books.bin"
 * - Read back and display in formatted table
 */
void exercise3(void) {
    printf("Exercise 3: Structure Serialization\n");
    printf("------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 4: Binary File with Header
 * =============================================================================
 * 
 * Task: Create a binary file format with a proper header.
 * 
 * Requirements:
 * - Define header struct with: magic number (0x42494E46), version (1),
 *   record_count, record_size, creation_time
 * - Create data records with: id, name (char[20]), score (float)
 * - Write header followed by 5 records
 * - Read back and validate magic number before reading data
 */
void exercise4(void) {
    printf("Exercise 4: Binary File with Header\n");
    printf("------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 5: Image Data Storage
 * =============================================================================
 * 
 * Task: Simulate storing grayscale image data in binary format.
 * 
 * Requirements:
 * - Create 50x50 "image" (2D array of unsigned char)
 * - Fill with gradient pattern (value = x + y)
 * - Write dimensions (width, height) followed by pixel data
 * - Read back and verify corners: [0,0], [0,49], [49,0], [49,49]
 */
void exercise5(void) {
    printf("Exercise 5: Image Data Storage\n");
    printf("-------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 6: Append Mode for Binary Files
 * =============================================================================
 * 
 * Task: Demonstrate appending records to existing binary file.
 * 
 * Requirements:
 * - Define simple record: id (int), value (double)
 * - Create file with 3 initial records
 * - Append 2 more records using "ab" mode
 * - Read all records and verify count is 5
 */
void exercise6(void) {
    printf("Exercise 6: Append Mode for Binary Files\n");
    printf("-----------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 7: Fixed-Width Integer Types
 * =============================================================================
 * 
 * Task: Use stdint.h types for portable binary storage.
 * 
 * Requirements:
 * - Create struct using: int8_t, int16_t, int32_t, int64_t, uint32_t
 * - Store maximum and minimum values for each type
 * - Write to file and read back
 * - Print sizes and verify values
 */
void exercise7(void) {
    printf("Exercise 7: Fixed-Width Integer Types\n");
    printf("--------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 8: Binary vs Text Size Comparison
 * =============================================================================
 * 
 * Task: Compare storage efficiency of binary vs text format.
 * 
 * Requirements:
 * - Create array of 50 large numbers (e.g., 1234567890)
 * - Write to text file (one per line)
 * - Write to binary file
 * - Compare and report file sizes
 * - Calculate space savings percentage
 */
void exercise8(void) {
    printf("Exercise 8: Binary vs Text Size Comparison\n");
    printf("-------------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 9: Simple Database Operations
 * =============================================================================
 * 
 * Task: Implement basic database operations on binary file.
 * 
 * Requirements:
 * - Create inventory item struct: id, name (char[30]), quantity, price
 * - Implement: create_db(), add_item(), list_items(), find_item(id)
 * - Test all operations
 * - Handle file-not-found gracefully
 */
void exercise9(void) {
    printf("Exercise 9: Simple Database Operations\n");
    printf("---------------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * EXERCISE 10: Chunked File Format
 * =============================================================================
 * 
 * Task: Implement a chunked/tagged binary file format.
 * 
 * Requirements:
 * - Define chunk header: type (4 chars), size (uint32_t)
 * - Write chunks: "HEAD" (version info), "META" (name/date), "DATA" (numbers)
 * - Read back and parse each chunk type
 * - Skip unknown chunk types gracefully
 */
void exercise10(void) {
    printf("Exercise 10: Chunked File Format\n");
    printf("---------------------------------\n");
    
    // TODO: Implement your solution here
    
    printf("\n");
}

/*
 * =============================================================================
 * MAIN FUNCTION
 * =============================================================================
 */
int main(void) {
    printf("\n");
    printf("╔═══════════════════════════════════════════════════════════════╗\n");
    printf("║          BINARY FILES IN C - PRACTICE EXERCISES               ║\n");
    printf("╚═══════════════════════════════════════════════════════════════╝\n\n");
    
    exercise1();
    exercise2();
    exercise3();
    exercise4();
    exercise5();
    exercise6();
    exercise7();
    exercise8();
    exercise9();
    exercise10();
    
    return 0;
}

/*
 * =============================================================================
 *                              ANSWER KEY
 * =============================================================================
 */

/* EXERCISE 1 SOLUTION:
void exercise1_solution(void) {
    int num = 123456;
    
    // Write
    FILE *fp = fopen("number.bin", "wb");
    if (fp == NULL) { perror("Error"); return; }
    fwrite(&num, sizeof(int), 1, fp);
    fclose(fp);
    
    // Get file size
    fp = fopen("number.bin", "rb");
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    printf("File size: %ld bytes (expected %zu)\n", size, sizeof(int));
    
    // Read back
    rewind(fp);
    int read_num;
    fread(&read_num, sizeof(int), 1, fp);
    fclose(fp);
    
    printf("Original: %d, Read: %d, Match: %s\n", 
           num, read_num, num == read_num ? "Yes" : "No");
}
*/

/* EXERCISE 2 SOLUTION:
void exercise2_solution(void) {
    double values[100];
    for (int i = 0; i < 100; i++) {
        values[i] = i * 0.1;
    }
    
    // Write
    FILE *fp = fopen("doubles.bin", "wb");
    fwrite(values, sizeof(double), 100, fp);
    fclose(fp);
    
    // Check size
    fp = fopen("doubles.bin", "rb");
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    printf("File size: %ld bytes (expected %zu)\n", size, sizeof(double) * 100);
    
    // Read back
    rewind(fp);
    double read_values[100];
    fread(read_values, sizeof(double), 100, fp);
    fclose(fp);
    
    printf("First 10: ");
    for (int i = 0; i < 10; i++) printf("%.1f ", read_values[i]);
    printf("\nLast 10:  ");
    for (int i = 90; i < 100; i++) printf("%.1f ", read_values[i]);
    printf("\n");
}
*/

/* EXERCISE 3 SOLUTION:
void exercise3_solution(void) {
    struct Book {
        char isbn[14];
        char title[50];
        char author[30];
        int year;
        float price;
    };
    
    struct Book books[] = {
        {"978-0131103", "C Programming", "K&R", 1988, 49.99},
        {"978-0596009", "Head First C", "Griffiths", 2012, 39.99},
        {"978-0131774", "Expert C", "Van Der Linden", 1994, 59.99},
        {"978-0321125", "Modern C", "Gustedt", 2019, 44.99},
        {"978-1491903", "21st Century C", "Klemens", 2014, 34.99}
    };
    int count = 5;
    
    FILE *fp = fopen("books.bin", "wb");
    fwrite(&count, sizeof(int), 1, fp);
    fwrite(books, sizeof(struct Book), count, fp);
    fclose(fp);
    
    // Read back
    fp = fopen("books.bin", "rb");
    int n;
    fread(&n, sizeof(int), 1, fp);
    
    printf("%-14s %-30s %-20s %5s %8s\n", "ISBN", "Title", "Author", "Year", "Price");
    
    struct Book b;
    for (int i = 0; i < n; i++) {
        fread(&b, sizeof(struct Book), 1, fp);
        printf("%-14s %-30s %-20s %5d $%7.2f\n", 
               b.isbn, b.title, b.author, b.year, b.price);
    }
    fclose(fp);
}
*/

/* EXERCISE 4 SOLUTION:
void exercise4_solution(void) {
    #define MAGIC 0x42494E46
    
    struct Header {
        uint32_t magic;
        uint32_t version;
        uint32_t record_count;
        uint32_t record_size;
        time_t created;
    };
    
    struct Record {
        int id;
        char name[20];
        float score;
    };
    
    struct Header h = {MAGIC, 1, 5, sizeof(struct Record), time(NULL)};
    struct Record records[] = {
        {1, "Alice", 95.5}, {2, "Bob", 87.0}, {3, "Carol", 92.3},
        {4, "David", 78.9}, {5, "Eva", 88.7}
    };
    
    FILE *fp = fopen("header_data.bin", "wb");
    fwrite(&h, sizeof(struct Header), 1, fp);
    fwrite(records, sizeof(struct Record), 5, fp);
    fclose(fp);
    
    // Read
    fp = fopen("header_data.bin", "rb");
    struct Header rh;
    fread(&rh, sizeof(struct Header), 1, fp);
    
    if (rh.magic != MAGIC) {
        printf("Invalid file!\n");
        fclose(fp);
        return;
    }
    
    printf("Version: %u, Records: %u\n", rh.version, rh.record_count);
    
    struct Record r;
    for (uint32_t i = 0; i < rh.record_count; i++) {
        fread(&r, sizeof(struct Record), 1, fp);
        printf("ID %d: %s - %.1f\n", r.id, r.name, r.score);
    }
    fclose(fp);
}
*/

/* EXERCISE 5 SOLUTION:
void exercise5_solution(void) {
    #define WIDTH 50
    #define HEIGHT 50
    
    unsigned char image[HEIGHT][WIDTH];
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            image[y][x] = (x + y) % 256;
        }
    }
    
    FILE *fp = fopen("image.bin", "wb");
    int dims[2] = {WIDTH, HEIGHT};
    fwrite(dims, sizeof(int), 2, fp);
    fwrite(image, sizeof(unsigned char), WIDTH * HEIGHT, fp);
    fclose(fp);
    
    // Read back
    fp = fopen("image.bin", "rb");
    int rdims[2];
    fread(rdims, sizeof(int), 2, fp);
    
    unsigned char rimage[HEIGHT][WIDTH];
    fread(rimage, sizeof(unsigned char), WIDTH * HEIGHT, fp);
    fclose(fp);
    
    printf("Dimensions: %dx%d\n", rdims[0], rdims[1]);
    printf("Corners: [0,0]=%d, [0,49]=%d, [49,0]=%d, [49,49]=%d\n",
           rimage[0][0], rimage[0][49], rimage[49][0], rimage[49][49]);
}
*/

/* EXERCISE 6 SOLUTION:
void exercise6_solution(void) {
    struct Record { int id; double value; };
    
    // Create with 3 records
    FILE *fp = fopen("append.bin", "wb");
    struct Record initial[] = {{1, 1.1}, {2, 2.2}, {3, 3.3}};
    fwrite(initial, sizeof(struct Record), 3, fp);
    fclose(fp);
    
    // Append 2 more
    fp = fopen("append.bin", "ab");
    struct Record extra[] = {{4, 4.4}, {5, 5.5}};
    fwrite(extra, sizeof(struct Record), 2, fp);
    fclose(fp);
    
    // Read all
    fp = fopen("append.bin", "rb");
    struct Record r;
    int count = 0;
    while (fread(&r, sizeof(struct Record), 1, fp) == 1) {
        printf("Record %d: id=%d, value=%.1f\n", ++count, r.id, r.value);
    }
    fclose(fp);
    
    printf("Total records: %d\n", count);
}
*/

/* EXERCISE 7 SOLUTION:
void exercise7_solution(void) {
    struct Portable {
        int8_t   i8;
        int16_t  i16;
        int32_t  i32;
        int64_t  i64;
        uint32_t u32;
    };
    
    struct Portable data = {
        INT8_MAX, INT16_MAX, INT32_MAX, INT64_MAX, UINT32_MAX
    };
    
    printf("Sizes: i8=%zu, i16=%zu, i32=%zu, i64=%zu, u32=%zu\n",
           sizeof(int8_t), sizeof(int16_t), sizeof(int32_t),
           sizeof(int64_t), sizeof(uint32_t));
    
    FILE *fp = fopen("portable.bin", "wb");
    fwrite(&data, sizeof(struct Portable), 1, fp);
    fclose(fp);
    
    fp = fopen("portable.bin", "rb");
    struct Portable r;
    fread(&r, sizeof(struct Portable), 1, fp);
    fclose(fp);
    
    printf("Values: %d, %d, %d, %ld, %u\n",
           r.i8, r.i16, r.i32, r.i64, r.u32);
}
*/

/* EXERCISE 8 SOLUTION:
void exercise8_solution(void) {
    int numbers[50];
    for (int i = 0; i < 50; i++) numbers[i] = 1234567890;
    
    // Text file
    FILE *fp = fopen("numbers.txt", "w");
    for (int i = 0; i < 50; i++) fprintf(fp, "%d\n", numbers[i]);
    fclose(fp);
    
    // Binary file
    fp = fopen("numbers.bin", "wb");
    fwrite(numbers, sizeof(int), 50, fp);
    fclose(fp);
    
    // Compare sizes
    fp = fopen("numbers.txt", "rb");
    fseek(fp, 0, SEEK_END);
    long text_size = ftell(fp);
    fclose(fp);
    
    fp = fopen("numbers.bin", "rb");
    fseek(fp, 0, SEEK_END);
    long bin_size = ftell(fp);
    fclose(fp);
    
    printf("Text size: %ld bytes\n", text_size);
    printf("Binary size: %ld bytes\n", bin_size);
    printf("Savings: %.1f%%\n", 100.0 * (text_size - bin_size) / text_size);
}
*/

/* EXERCISE 9 SOLUTION:
struct Item { int id; char name[30]; int quantity; float price; };

void create_db(void) {
    FILE *fp = fopen("inventory.bin", "wb");
    int count = 0;
    fwrite(&count, sizeof(int), 1, fp);
    fclose(fp);
}

void add_item(struct Item *item) {
    FILE *fp = fopen("inventory.bin", "r+b");
    int count;
    fread(&count, sizeof(int), 1, fp);
    fseek(fp, 0, SEEK_END);
    fwrite(item, sizeof(struct Item), 1, fp);
    count++;
    rewind(fp);
    fwrite(&count, sizeof(int), 1, fp);
    fclose(fp);
}

void list_items(void) {
    FILE *fp = fopen("inventory.bin", "rb");
    if (!fp) { printf("No database\n"); return; }
    int count;
    fread(&count, sizeof(int), 1, fp);
    struct Item item;
    for (int i = 0; i < count; i++) {
        fread(&item, sizeof(struct Item), 1, fp);
        printf("%d: %s (qty: %d) $%.2f\n", 
               item.id, item.name, item.quantity, item.price);
    }
    fclose(fp);
}
*/

/* EXERCISE 10 SOLUTION:
void exercise10_solution(void) {
    struct Chunk { char type[4]; uint32_t size; };
    
    FILE *fp = fopen("chunked.bin", "wb");
    
    // HEAD chunk
    struct Chunk head = {{'H','E','A','D'}, sizeof(uint32_t)};
    uint32_t version = 1;
    fwrite(&head, sizeof(struct Chunk), 1, fp);
    fwrite(&version, sizeof(uint32_t), 1, fp);
    
    // META chunk
    char meta[] = "Test File 2024";
    struct Chunk metac = {{'M','E','T','A'}, strlen(meta) + 1};
    fwrite(&metac, sizeof(struct Chunk), 1, fp);
    fwrite(meta, 1, strlen(meta) + 1, fp);
    
    // DATA chunk
    int data[] = {10, 20, 30};
    struct Chunk datac = {{'D','A','T','A'}, sizeof(data)};
    fwrite(&datac, sizeof(struct Chunk), 1, fp);
    fwrite(data, sizeof(int), 3, fp);
    
    fclose(fp);
    
    // Read
    fp = fopen("chunked.bin", "rb");
    struct Chunk c;
    while (fread(&c, sizeof(struct Chunk), 1, fp) == 1) {
        printf("Chunk: %.4s (%u bytes)\n", c.type, c.size);
        if (memcmp(c.type, "HEAD", 4) == 0) {
            uint32_t v; fread(&v, sizeof(uint32_t), 1, fp);
            printf("  Version: %u\n", v);
        } else if (memcmp(c.type, "META", 4) == 0) {
            char *m = malloc(c.size);
            fread(m, 1, c.size, fp);
            printf("  Meta: %s\n", m);
            free(m);
        } else if (memcmp(c.type, "DATA", 4) == 0) {
            int *d = malloc(c.size);
            fread(d, 1, c.size, fp);
            printf("  Data: %d %d %d\n", d[0], d[1], d[2]);
            free(d);
        } else {
            fseek(fp, c.size, SEEK_CUR);
        }
    }
    fclose(fp);
}
*/
Exercises - C Programming Tutorial | DeepML