File input and output
Read and write text files with ifstream and ofstream, and check file operations for failure.
Learning objectives
- Open a file for reading and writing.
- Use
std::ifstreamandstd::ofstream. - Check whether a file opened successfully.
- Explain why streams should be checked and closed safely.
Prerequisites: understand variables, functions, strings, and console input/output. Review Variables, Functions, Strings, and Console input/output first. Examples use C++17.
Why files?
Console input disappears when a program ends unless the user saves it elsewhere. A file lets a program store information for a later run, such as settings, reports, or records.
Write a text file
#include <fstream>
#include <iostream>
int main() {
std::ofstream output{"notes.txt"};
if (!output) {
std::cerr << "Could not open notes.txt\n";
return 1;
}
output << "C++ practice\n";
output << "Review vectors tomorrow\n";
}std::ofstream opens a file for output. By default, opening an output file this way truncates an existing file. If the file cannot be opened, the stream enters a failure state. Check the stream before writing.
Read a text file line by line
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream input{"notes.txt"};
if (!input) {
std::cerr << "Could not open notes.txt\n";
return 1;
}
std::string line;
while (std::getline(input, line)) {
std::cout << line << '\n';
}
}std::ifstream opens a file for input. The loop continues while getline successfully reads a line. This is a common and reliable pattern for line-based text files.
Append instead of replace
To add content to an existing file rather than replace its previous contents, use the append mode:
std::ofstream log{"activity.txt", std::ios::app};Always choose file mode deliberately. Output mode without append normally truncates an existing file; append mode writes at the end.
Resource management
File streams close their file when the stream object is destroyed. This is an example of RAII (Resource Acquisition Is Initialization): the object's lifetime manages the resource lifetime. You can call close() explicitly when you need to check the result of closing or finish the file before the stream object leaves scope, but ordinary code should rely on automatic cleanup.
Common mistakes
- Assuming a file opened successfully without checking stream state.
- Using a relative path without knowing the program's working directory.
- Accidentally truncating an existing file when append mode was intended.
- Using
while (!input.eof())as the read loop. Check the read operation itself withwhile (getline(input, line)). - Expecting a file to be created in the same directory as the source code; the working directory determines relative paths.
Practice
- Write three lines to a file and read them back.
- Change the output stream to append mode and confirm that old content remains.
- Try opening a file that does not exist for input and show a clear error.
- Write a program that counts the number of lines in a text file.
Check your understanding
Why is while(getline(input, line)) preferred to while(!input.eof())?
Answer: It processes a line only when the read succeeds. EOF is usually detected during an attempted read, so checking it before reading can cause an extra failed iteration.
Practice solutions
Show worked solutions
- Open an
std::ofstream, check it, write each line followed by'\n', let it close, then open anstd::ifstreamand print each line with awhile (std::getline(input, line))loop. - Open the output stream with
std::ios::app, for examplestd::ofstream output{"notes.txt", std::ios::app};. Check the stream before writing; append mode preserves existing content. - Check
if (!input)immediately after constructing the input stream. Print a diagnostic tostd::cerrand return a non-zero status if opening failed. - After checking the input stream, initialize
std::size_t line_count = 0;and increment it insidewhile (std::getline(input, line)). Print the count after the loop.
Summary
Use file streams for persistent text data, check stream state after opening, choose truncation or append mode intentionally, and let RAII close the file when the stream leaves scope.