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]