NBC 103 • Unit 516 min readHigh Exam Frequency

Binary File I/O (fread/fwrite) & Random File Access (fseek/ftell)

Unit 5: Searching, Sorting, Dynamic Memory & File HandlingProblem Solving Using C

👨‍🏫 Professor's Mental Model: The Sequential Audio Tape vs Laser Turntable Arm

Text File purane jamane ki cassette tape jaisi hai jisme gana sunne ke liye reel ko shuru se aage tak chalana padta hai (Sequential Access). Binary File aur fseek ek modern DVD laser arm ya vinyl turntable jaisa hai: aap direct track 5 par laser ko drop kar sakte ho (Random Direct Access)! fread aur fwrite pure ke pure student structure record ko bina kisi conversion ke direct silicon RAM se disk platter par copy kar dete hain!

Academic Lecture Notes & Solved Study Pages

Unit 5 • Core Concepts, Step-by-Step Proofs & Notebook Solutions

3 Notebook Pages
NOTEBOOK PAGE 1 OF 3

1. Text Files vs Binary Files

Text Files (`.txt`):

Store human-readable ASCII/UTF-8 characters. The OS performs line-ending translations (e.g. converting `\n` to carriage return `\r\n` on Windows). Numbers are stored as digit characters ('1', '0', '0' takes 3 bytes).

Binary Files (`.dat`, `.bin`):

Store raw binary data bytes exactly as structured in CPU RAM. No newline translation occurs. An integer `100` is stored in its raw 4-byte two's complement binary representation. Faster, compact, and immune to formatting corruption.

NOTEBOOK PAGE 2 OF 3

2. Block Record I/O: fread() and fwrite()

Ideal for persisting complete structs and arrays directly to disk:

fwrite(buffer_address, item_size, item_count, file_ptr):

Writes `count` items of `size` bytes from RAM into binary file.

Example: `fwrite(&s1, sizeof(struct Student), 1, fp);`

fread(buffer_address, item_size, item_count, file_ptr):

Reads `count` items of `size` bytes from binary file directly into RAM buffer.

Example: `fread(&s1, sizeof(struct Student), 1, fp);`

Returns the actual count of items successfully read (used to detect EOF).

NOTEBOOK PAGE 3 OF 3

3. Random File Access: fseek(), ftell() & rewind()

Allows non-sequential, direct jumping to any byte offset inside a file:

`fseek(fp, offset, origin)`:

Repositions the internal file pointer to a new location.

- `offset`: Long integer representing bytes to move (positive or negative).
- `origin` (Seek Flags in `<stdio.h>`):

1. `SEEK_SET` (0): Beginning of file.

2. `SEEK_CUR` (1): Current file pointer location.

3. `SEEK_END` (2): End of file.

`ftell(fp)`:

Returns the current byte position of the file pointer relative to the start.

Useful trick to compute file size:

`fseek(fp, 0, SEEK_END); long file_size = ftell(fp);`

`rewind(fp)`:

Resets file pointer back to the beginning (`SEEK_SET`), clearing all error indicators.

Comparative Analysis: Text Files vs Binary Files
FeatureText Files (.txt)Binary Files (.dat, .bin)
Storage FormatASCII / Unicode charactersExact binary bytes as stored in RAM
Human ReadabilityEasily readable in Notepad/Text editorUnreadable garbage symbols in text editors
Line End TranslationConverts \n to \r\n on WindowsNo translation: strictly raw byte stream
Storage EfficiencyLess efficient for numbers (e.g. 12345 takes 5B)High: 32-bit int always takes exactly 4 Bytes
I/O Functions Usedfprintf, fscanf, fgetc, fgetsfread, fwrite, fseek, ftell
File Mode Flags"r", "w", "a""rb", "wb", "ab", "rb+"

Interactive Tested Code Example

#include <stdio.h>
#include <stdlib.h>

struct Student {
    int id;
    char name[20];
    float marks;
};

int main(void) {
    FILE *fp = fopen("students.dat", "wb+");
    if (!fp) return 1;

    struct Student s[3] = {
        {101, "Alice", 89.5f},
        {102, "Bob", 76.0f},
        {103, "Charlie", 94.0f}
    };

    // 1. Write array of structures using fwrite
    fwrite(s, sizeof(struct Student), 3, fp);
    printf("Successfully written 3 student records to binary file.\n\n");

    // 2. Random Access: Jump directly to Record 2 (Bob) using fseek
    struct Student target;
    fseek(fp, 1 * sizeof(struct Student), SEEK_SET); // Skip record 0
    fread(&target, sizeof(struct Student), 1, fp);

    printf("=== RANDOM ACCESS LOOKUP (RECORD 2) ===\n");
    printf("ID:    %d\n", target.id);
    printf("Name:  %s\n", target.name);
    printf("Marks: %.1f%%\n\n", target.marks);

    // 3. Compute Total File Size using ftell
    fseek(fp, 0, SEEK_END);
    long total_bytes = ftell(fp);
    printf("Total Binary File Size: %ld Bytes (%zu Bytes per record)\n", total_bytes, sizeof(struct Student));

    fclose(fp);
    return 0;
}
💡 Note:Exemplifies binary block I/O: writing records with fwrite(), performing O(1) random seeking with fseek(fp, offset, SEEK_SET) to fetch Record 2 directly, and computing file size using ftell().

🎯 University Exam Scoring Blueprint

  • In university exams, always specify the 3 seek flags: SEEK_SET (start), SEEK_CUR (current), SEEK_END (end).
  • Explain the trick to find file size: fseek(fp, 0, SEEK_END); size = ftell(fp);.
  • Highlight that binary modes append 'b' to mode strings: 'rb', 'wb', 'ab'.

Top Viva Questions on Binary File I/O (fread/fwrite) & Random File Access (fseek/ftell)

2 Questions
1

What is the return value of fread() and fwrite()?

2

What is the difference between fseek(fp, 0, SEEK_SET) and rewind(fp)?