C++ Files (fstream)
The header fstream provides file streams that work like cout and cin: std::ofstream writes a file, std::ifstream reads one and std::fstream can do both. Files your program creates appear in the editor's file list.
Writing a file
#include <fstream>
#include <iostream>
int main() {
std::ofstream out("marks.txt"); // create, or empty if it exists
if (!out) {
std::cout << "Could not create marks.txt\n";
return 1;
}
out << "Asha 91\n";
out << "Ravi 78\n";
out << "Meera 85\n";
std::cout << "written\n";
return 0; // out closes itself here
}written
A stream converts to false when something went wrong, so if (!out) checks that the file opened. The file is closed automatically when the stream object goes away (RAII); out.close() closes it earlier if needed.
Reading values
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ofstream("marks.txt") << "Asha 91\nRavi 78\nMeera 85\n";
std::ifstream in("marks.txt");
if (!in) {
std::cout << "Could not open marks.txt\n";
return 1;
}
std::string name;
int mark, total = 0, count = 0;
while (in >> name >> mark) { // stops at the end of the file
std::cout << name << " scored " << mark << "\n";
total += mark;
count++;
}
std::cout << "Average: " << static_cast<double>(total) / count << "\n";
return 0;
}Asha scored 91 Ravi scored 78 Meera scored 85 Average: 84.6667
The loop condition is the read itself, so it stops cleanly at the end of the file. Avoid while (!in.eof()), which runs one time too many.
Line by line
#include <fstream>
#include <iostream>
#include <string>
int main() {
{
std::ofstream out("poem.txt");
out << "Roses are red,\nviolets are blue,\nC++ is fast,\nand so are you.\n";
}
std::ifstream in("poem.txt");
std::string line;
int n = 0;
while (std::getline(in, line)) {
std::cout << ++n << ": " << line << "\n";
}
return 0;
}1: Roses are red, 2: violets are blue, 3: C++ is fast, 4: and so are you.
Appending
Open with std::ios::app to add at the end instead of starting over:
#include <fstream>
#include <iostream>
#include <string>
int main() {
for (int run = 1; run <= 3; run++) {
std::ofstream log("log.txt", std::ios::app);
log << "entry " << run << "\n";
}
std::ifstream in("log.txt");
std::string line;
while (std::getline(in, line)) std::cout << line << "\n";
return 0;
}entry 1 entry 2 entry 3
Splitting a line
std::istringstream (header sstream) reads values from a string, which is handy for lines in a fixed format such as comma-separated values: std::getline(row, field, ',') reads up to the next comma.
Common mistakes
- Forgetting to check that the file opened. A misspelled name gives an empty read with no error message unless you test the stream.
- Mixing
in >> xandgetline: after>>the newline stays in the stream, and the nextgetlinereturns an empty line. Callin.ignore()in between, or read everything withgetline. - Opening an
ofstreamon a file you meant to keep: withoutstd::ios::appits contents are erased.
Practice exercises
- Write the names of five students to
class.txt, one per line, then read the file and count the names. - Copy
poem.txtintocopy.txtline by line. - Read a file of
name,marklines withgetline(..., ',')and print the best student.