C/C++ Arena

Step 4 of 6

Reading files with ifstream

Files use the same stream interface once more. std::ifstream (from <fstream>) opens a file for reading, and then >> and std::getline work exactly as they do on std::cin.

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

int main() {
    {
        std::ofstream out("notes.txt");       // create a small file to read back
        out << "first line\n\nthird line\n";
    }                                         // out is destroyed here, closing the file

    std::ifstream in("notes.txt");
    if (!in) {
        std::cout << "could not open notes.txt\n";
        return 1;
    }
    std::string line;
    int n = 0;
    while (std::getline(in, line)) {
        n++;
        std::cout << n << ": [" << line << "]\n";
    }

    std::ifstream missing("no_such_file.txt");
    std::cout << "missing opened? " << (missing ? "yes" : "no") << "\n";
}
1: [first line]
2: []
3: [third line]
missing opened? no

How it works

Returning "maybe a value"

Your function needs to say either "here are the lines" or "couldn't open the file". std::optional<T> (from <optional>) is made for that: it either holds a T or holds nothing.

std::optional<int> parse_age(const std::string& s);   // declaration
return 42;             // an optional holding 42
return std::nullopt;   // an empty optional

The caller checks with if (result) and reads the value with *result. Error handling gets its own module later.

Your turn: write std::optional<std::vector<std::string>> read_lines(const std::string& path) returning the file's lines without their newlines, skipping empty lines, or std::nullopt if the file can't be opened.

Previous: Building strings with ostringstream Next: Writing files with ofstream