CSS Prepare

optional · CSS study notes

21. File Processing

Covers the modes and techniques for reading, writing, and modifying files:

ModeUse case
Read (ios::in)Loading existing data
Write (ios::out • ios::trunc)Creating a fresh file, discarding old content
Append (ios::app)Adding new records without disturbing existing ones
Binary (ios::binary)Required for raw struct/class I/O and for seekg/seekp positional access
Read + Write (`ios::in \ios::out`)Needed for in-place updates (read a record, then overwrite it)
fstream file("students.dat", ios::in | ios::out | ios::binary);
// combining flags with | lets one stream object both read AND write the same file

See the Random Access Files page for a full in-place update example using this combination.

Full lifecycle example — combining modes for a real update workflow

#include <fstream>
#include <iostream>
using namespace std;

struct Product { int id; char name[20]; double price; };

int main()
{
    // 1. WRITE mode -- create the file fresh
    ofstream fout("products.dat", ios::out | ios::binary | ios::trunc);
    Product p1 = {1, "Pen", 2.5}, p2 = {2, "Book", 15.0};
    fout.write((char*)&p1, sizeof(Product));
    fout.write((char*)&p2, sizeof(Product));
    fout.close();

    // 2. APPEND mode -- add a new record without touching existing ones
    ofstream fapp("products.dat", ios::app | ios::binary);
    Product p3 = {3, "Notebook", 8.0};
    fapp.write((char*)&p3, sizeof(Product));
    fapp.close();

    // 3. READ + WRITE mode -- update an existing record in place
    fstream fedit("products.dat", ios::in | ios::out | ios::binary);
    fedit.seekp(0 * sizeof(Product), ios::beg);   // go to record 0
    p1.price = 3.0;                                // updated price
    fedit.write((char*)&p1, sizeof(Product));
    fedit.close();

    return 0;
}

Choosing the right mode — decision guide

GoalMode(s) to use
Start completely fresh, losing old dataios::out (implies ios::trunc)
Add new data, keep everything oldios::app
Update specific existing records`ios::in \
Store/retrieve raw objects, not textalways add ios::binary

Important MCQs

  1. To update a specific existing record in place, you need to open the file with:
    • a) ios::app only b) ios::out only c) ios::in combined with ios::out d) ios::trunc only
  2. Using ios::out alone (without ios::app) when opening an existing file will:
    • a) Append to it b) Truncate/discard its existing content c) Refuse to open d) Convert it to binary
  3. Which flag is essential when reading/writing raw struct/class objects rather than text?
    • a) ios::app b) ios::trunc c) ios::binary d) ios::ate

Self-Test Questions

  1. Why does step 1 in the example use ios::trunc explicitly?
  2. What would happen if step 2 used ios::out instead of ios::app?
  3. Why does updating a specific record (step 3) require both ios::in and ios::out together?

📌 Sample & Repeated FPSC Questions (2016–2026)

2020, Paper I, Q5(b) (15 marks) — Write C++ programs to compute following: i. Add a student ii. Add a course iii. Find a student with respect to CGPA iv. Add a Teacher v. Update a student. (Full solution: Classes and Objects — Exam Practice → "University Records System" page.)

This is FPSC's best real illustration of "choosing the right mode per operation" — the exact decision this page's guide above walks through, but applied across three separate files at once:

  • Add a student / course / teacher → students.dat / courses.dat / teachers.dat, each opened ios::app | ios::binary — a brand-new record only, existing ones must survive.
  • Find a student by CGPA → students.dat, opened read-only (ifstream, ios::binary) — pure scanning, nothing is modified.
  • Update a student → students.dat, opened ios::in | ios::out | ios::binary — must locate an existing record AND overwrite it in place, so both directions are needed on one stream object.

Exam angle: a 15-mark "design and persist a system" question like this is really three or four separate file-processing sub-questions in disguise — grade each operation independently on whether it opens its file with the correct combination of modes, not just on whether the code compiles.