10.2 Line-by-Line Reading and Processing
Reading a whole file is simple, but real files can be large. If a log file has millions of lines, loading it all into memory is wasteful. Line-by-line reading processes one line at a time.
std::getline
std::getline reads text one line at a time. It removes the line break and returns a stream state that works naturally in a while loop.
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream input("quotes.txt");
std::string line;
while (std::getline(input, line)) {
std::cout << line << std::endl;
}
return 0;
}When there are no more lines, std::getline(input, line) becomes false and the loop stops.
C++ streams are RAII objects. The file is closed automatically when input leaves scope, even if an exception leaves the scope early.
Token-Based Reading
Sometimes a file is simple and token-based, such as a file of numbers separated by whitespace. The extraction operator >> can read one token at a time.
#include <fstream>
#include <iostream>
int main() {
std::ifstream input("numbers.txt");
int value;
int total = 0;
while (input >> value) {
total += value;
}
std::cout << "Total: " << total << std::endl;
return 0;
}Use token extraction when the file format is simple and whitespace-separated. Use std::getline when you want full control over each line.
Parsing Words
The program below reads quotes.txt, removes punctuation around each word, and writes each cleaned word into words.txt. In this example, quotes.txt contains:
Talk is cheap. Show me the code.
Code never lies, comments sometimes do.
Stay Hungry Stay Foolish.#include <cctype>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
std::string clean_word(std::string word) {
while (!word.empty() && std::ispunct(static_cast<unsigned char>(word.front()))) {
word.erase(word.begin());
}
while (!word.empty() && std::ispunct(static_cast<unsigned char>(word.back()))) {
word.pop_back();
}
return word;
}
int main() {
std::ifstream input("quotes.txt");
std::ofstream output("words.txt");
std::string line;
while (std::getline(input, line)) {
std::istringstream row(line);
std::string word;
while (row >> word) {
std::string cleaned = clean_word(word);
if (!cleaned.empty()) {
output << cleaned << '\n';
}
}
}
return 0;
}After the program runs, words.txt becomes:
Talk
is
cheap
Show
me
the
code
Code
never
lies
comments
sometimes
do
Stay
Hungry
Stay
Foolish