SrcForge

Lesson 25

File Handling

Covers file stream classes, opening and closing files, reading and writing, file modes, and checking whether a file opened successfully.

Lesson content

What is file handling?

File handling is the process of creating, opening, reading, writing, updating, and closing files using C++. Unlike variables stored in memory, files store data permanently on a storage device such as a hard disk or SSD.

  • Your program writes information into the notebook
  • Later, it can reopen the notebook and read the saved information

Why does file handling exist?

  • Without files, data is lost when the program ends
  • Users must enter the same information repeatedly
  • Programs cannot maintain records
  • File handling solves these problems by providing permanent data storage

Real-world use cases

  • Student management systems
  • Banking applications
  • Inventory systems
  • Employee records
  • Game save files
  • Application logs
  • Configuration files
  • Report generation

Prerequisites

  • Variables
  • Functions
  • Strings
  • Loops
  • Structures or classes (helpful)
  • Basic C++ syntax

File stream classes

C++ provides three primary file stream classes in the <fstream> header.

  • ifstream: read data from a file
  • ofstream: write data to a file
  • fstream: read and write data
#include <fstream>

Opening a file

// Write to a file
ofstream file("data.txt");
// If the file doesn't exist, it is created.

// Read from a file
ifstream file2("data.txt");
// The file must already exist.

// Read and write
fstream file3("data.txt");

Closing a file

Always close a file after using it.

file.close();

Although files are usually closed automatically when the stream object is destroyed, explicitly closing them is considered good practice.

Writing to a file

Use the insertion operator (<<) just like cout.

ofstream file("data.txt");

file << "Hello World";

file.close();

// Contents of data.txt:
// Hello World

Reading from a file

Use the extraction operator (>>) or getline().

ifstream file("data.txt");

string text;

file >> text;

cout << text;

// Output: Hello
// Notice that >> reads only until the first whitespace.

Reading an entire line

string line;

getline(file, line);

// Example: "Hello World"
// Entire line is read.

File opening modes

  • ios::in – open for reading
  • ios::out – open for writing
  • ios::app – append to the end of the file
  • ios::trunc – erase existing file contents
  • ios::binary – open in binary mode
  • ios::ate – move to the end immediately after opening
ofstream file("data.txt", ios::app);

// This appends data instead of overwriting the file.

Checking if a file opened successfully

Always verify that the file opened correctly.

ifstream file("data.txt");

if (file.is_open())
{
    cout << "File opened successfully.";
}
else
{
    cout << "Unable to open file.";
}

Example 1: Writing to a file

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

int main()
{
    ofstream file("student.txt");

    file << "Alice";

    file.close();

    cout << "Data written successfully.";

    return 0;
}

Example 2: Reading from a file

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

int main()
{
    ifstream file("student.txt");

    string name;

    file >> name;

    cout << name << endl;

    file.close();

    return 0;
}

Example 3: Reading an entire file

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

int main()
{
    ifstream file("notes.txt");

    string line;

    while (getline(file, line))
    {
        cout << line << endl;
    }

    file.close();

    return 0;
}

Example 4: Appending data

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

int main()
{
    ofstream file("log.txt", ios::app);

    file << "New log entry" << endl;

    file.close();

    return 0;
}

Example 5: Reading and writing using fstream

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

int main()
{
    fstream file("data.txt", ios::in | ios::out | ios::app);

    if (!file.is_open())
    {
        cout << "Unable to open file.";

        return 1;
    }

    file << "Welcome to C++" << endl;

    file.close();

    return 0;
}

Common mistakes and pitfalls

  • Opening a file without checking success. Fix: use if (file.is_open()) or if (!file)
  • Forgetting to close the file. Fix: call file.close() when finished
  • Using >> to read complete sentences. Fix: use getline() for entire lines
  • Using ios::out when you meant to append. Fix: use ios::app to preserve existing data
  • Assuming the file always exists. Fix: handle missing or inaccessible files gracefully

Best practices

  • Always check whether a file opened successfully before reading or writing
  • Use getline() when reading text that may contain spaces
  • Close files as soon as you're done with them
  • Use meaningful file names and organize file paths clearly
  • Handle errors such as missing files or permission issues
  • Use binary mode (ios::binary) when working with non-text data

When not to use this

  • Data must be stored in a relational database
  • High-performance binary serialization is required
  • Multiple processes need coordinated access to the same data without proper synchronization
  • Sensitive information requires encryption before storage

Summary

  • File handling enables permanent data storage
  • Include the <fstream> header to use file streams
  • ifstream reads from files
  • ofstream writes to files
  • fstream supports both reading and writing
  • Always verify that a file opened successfully
  • Use getline() to read complete lines
  • Use ios::app to append data without overwriting existing content
  • Close files after use to release resources

Frequently asked questions

What is the difference between ifstream, ofstream, and fstream?

ifstream reads from a file, ofstream writes to a file, and fstream both reads from and writes to a file.

Why should I check if a file opened successfully?

A file may fail to open because it doesn't exist, the path is incorrect, or the program lacks permission. Checking prevents unexpected runtime errors.

What is the difference between >> and getline()?

>> reads input until the first whitespace, while getline() reads an entire line, including spaces.

How do I append data instead of overwriting a file?

Open the file with the append mode, such as ofstream file("data.txt", ios::app);. New data is added to the end of the file instead of replacing the existing contents.

Should I always call close()?

Yes. While stream objects usually close automatically when they go out of scope, explicitly calling close() makes your intent clear and releases file resources as soon as you're finished using them.