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
std::ifstream in(path);tries to open the file. If it fails (the file doesn't exist, or you lack permission), the stream starts in a failed state, soif (!in)catches it. Always check.std::getlinestrips the newline, and an empty line comes back as an empty string, which is why line 2 prints[].- There's no
close()to forget. The stream's destructor closes the file when it goes out of scope. That's RAII, and the inner{ }block in the example uses it to make sure the file is fully written before it's read.
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