STL 以「容器、迭代器、演算法」三位一體聞名。標準庫提供 istream_iterator 但按詞元(空白分隔)讀取,無法直接按「行」讀取。本文實作一個符合 InputIterator 概念的 line_iterator,支援 getline 語意,可直接搭配 vector、sort、copy 等演算法。
vector<string> v; string tmp;
while (getline(cin, tmp)) v.push_back(tmp);
sort(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
line_iterator begin(cin), end; // end 為預設構造(EOF 狀態)
vector<string> v(begin, end); // 區間構造自動讀取所有行
sort(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
#include <iostream>
#include <string>
#include <iterator>
class line_iterator {
std::istream *in;
std::string line;
bool is_valid;
void read() {
if (*in) std::getline(*in, line);
is_valid = static_cast(*in);
}
public:
// Iterator traits
using iterator_category = std::input_iterator_tag;
using value_type = std::string;
using difference_type = std::ptrdiff_t;
using pointer = const std::string*;
using reference = const std::string&;
line_iterator() : in(&std::cin), is_valid(false) {}
explicit line_iterator(std::istream& s) : in(&s) { read(); }
reference operator*() const { return line; }
pointer operator->() const { return &line; }
line_iterator& operator++() { read(); return *this; } // 前置++
line_iterator operator++(int) { line_iterator tmp=*this; read(); return tmp; } // 後置++
bool operator==(const line_iterator& rhs) const {
if (in == rhs.in && is_valid == rhs.is_valid) return true;
if (!is_valid && !rhs.is_valid) return true; // 皆為 EOF
return false;
}
bool operator!=(const line_iterator& rhs) const { return !(*this == rhs); }
};
| 成員 | 用途 |
|---|---|
istream* in | 綁定輸入流,預設 cin |
string line | 緩存當前行 |
bool is_valid | 標記是否成功讀取(EOF 為 false) |
read() | 核心邏輯:嘗試 getline,更新 is_valid |
| Iterator traits | 滿足 STL 演算法對迭代器類別的靜態檢查 |
| 比較運算子 | 雙重判斷:同流同狀態,或雙皆 EOF 視為相等 |
vector(begin, end) 內部循環 while (it != end) { *it; ++it; }。++it 呼叫 read() 讀取下一行。is_valid=false,與預設構造的 end 比較相等,循環終止。line_iterator it(fin), end;transform、find_if 等演算法處理每行。