cpp-archivos-texto

Reading and Writing Text Files in C++

  • 4 min

A text file is a file that stores information as readable characters so that a program can save and retrieve data.

So far, all the programs we’ve written have “amnesia.” When you close them, they lose all information. Variables are destroyed and RAM is freed.

For our programs to be useful in the real world, we need persistence. And the most basic form of persistence is Text Files.

In C++, file handling is done through the standard library <fstream> (File Stream). If you already know how to use std::cout and std::cin to write to the console, you have 90% of the work done, because files work exactly the same: they are data streams.

The fstream Classes

To work with files, we need to include the header:

#include <fstream>
Copied!

This library provides us with three fundamental classes:

  1. std::ofstream (Output File Stream): To write to files (create or overwrite them).
  2. std::ifstream (Input File Stream): To read existing files.
  3. std::fstream: For both at the same time (reading and writing).

These classes follow the RAII principle. When the file object is destroyed (goes out of scope), the file is closed automatically. Calling .close() is not mandatory, although it is sometimes useful to do it manually.

Writing to a File (ofstream)

Writing to a file is as simple as writing to cout. We use the insertion operator <<.

#include <iostream>
#include <fstream>
#include <string>

int main() {
    // 1. Open the file (it is created if it doesn't exist)
    std::ofstream archivo("notas.txt");

    // 2. Check if it opened correctly
    if (archivo.is_open()) {
        
        // 3. Write data
        archivo << "Todo List:\n";
        archivo << "1. Learn C++\n";
        archivo << "2. Master pointers\n";
        
        int prioridad = 10;
        archivo << "Priority: " << prioridad << "\n";

        // 4. Optional: Close manually
        archivo.close(); 
        
        std::cout << "File written successfully.\n";
    } else {
        std::cerr << "Error opening file.\n";
    }
}
Copied!

If you run this, you’ll see a file named notas.txt appears in your executable’s folder.

Opening Modes

By default, ofstream overwrites the file if it already exists (deletes previous content). If we want to append content to the end, we need to specify this in the constructor using “flags.”

// std::ios::app -> Append (Add to the end)
std::ofstream archivo("log.txt", std::ios::app);
archivo << "New log line\n";
Copied!

Reading from a File (ifstream)

Reading is a bit more delicate because the file might not exist or could have an unexpected format.

We have two main ways to read:

  1. Word by word (using >>): Same as cin, it stops at spaces.
  2. Line by line (using std::getline): The most common for text files.

Line-by-Line Reading

#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::ifstream archivo("notas.txt");

    if (archivo.is_open()) {
        std::string linea;

        // While loop: "As long as we can get a line from the file..."
        while (std::getline(archivo, linea)) {
            std::cout << "Read: " << linea << "\n";
        }
        
        archivo.close();
    } else {
        std::cout << "Could not open the file.\n";
    }
}
Copied!

The while(std::getline(archivo, linea)) pattern is the standard way to read a whole file in C++. It is safe and robust.

Formatted Reading (>>)

If we know the file has a fixed structure (e.g., “Name Age Score”), we can read directly into variables.

Imagine a file datos.txt:

Luis 35 100
Ana 28 95
Copied!

We can read it like this:

std::ifstream archivo("datos.txt");
std::string nombre;
int edad, puntos;

while (archivo >> nombre >> edad >> puntos) {
    std::cout << nombre << " is " << edad << " years old.\n";
}
Copied!

The >> operator automatically converts the text to an integer (int). If it finds something that is not a number where it expected one, the stream enters an error state and the loop stops.

Error Checking

It is vital to always check if the file was opened. The .is_open() method is your best friend.

The most common reasons for a failed opening are:

  • The file does not exist (in read mode).
  • You don’t have write permissions in that folder.
  • The file path is incorrect (watch out for relative vs absolute paths).

File Paths

In the examples, we’ve only used "notas.txt". This looks for the file in the current working directory (which is usually where the executable is or the project folder, depending on how you run it).

If you want to specify a path, remember that in Windows, the backslash \ is an escape character, so you must double it \\ or use the forward slash / (which C++ and Windows accept perfectly).

// Windows (Option A - Escaped)
std::ifstream f1("C:\\Users\\Luis\\Documents\\datos.txt");

// Windows/Linux/Mac (Option B - Forward slash - PREFERRED)
std::ifstream f2("C:/Users/Luis/Documents/datos.txt");
Copied!