c
exercises
exercises.c🔧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);
}
*/