C++で文字列を1行ごとに処理する方法
以下の例のようにRange-based for loopを使用して処理できるようにします。
for (auto& line : lines("1,2,3\n4,5,6\n7,8,9")){ cout << '[' << line << ']' << endl; }
コード
using namespace std; class LinesIterator : public iterator<input_iterator_tag, string>{ public: LinesIterator(istream& stream) :stream(&stream), isValid(!stream.eof()){ ++(*this); } LinesIterator(){ } const string& operator*() const { return line; } const string* const operator->() const { return &line; } iterator& operator++() { if (isValid && !getline(*stream, line)){ isValid = false; } return *this; } bool operator==(const LinesIterator &x) const { return (!isValid && !x.isValid) || (this == &x); } bool operator!=(const LinesIterator &x) const { return !(*this == x); } static LinesIterator endItr; private: string line; istream* const stream = nullptr; bool isValid = false; }; LinesIterator LinesIterator::endItr; class StreamLines{ public: StreamLines(istream& stream) :stream(stream) { } LinesIterator begin() { return LinesIterator(stream); } LinesIterator& end() const { return LinesIterator::endItr; } private: istream& stream; }; class StringLines : public StreamLines { public: StringLines(const string& str) :ss(str), StreamLines(ss){ } private: istringstream ss; }; StreamLines lines(istream& stream){ return StreamLines(stream); } StringLines lines(const string& str){ return StringLines(str); } int main(){ for (auto& line : lines("1,2,3\n4,5,6\n7,8,9")){ cout << '[' << line << ']' << endl; } cout << endl; }
結果
[1,2,3] [4,5,6] [7,8,9]