Document.h

#include <vector> #include <list> #include <iostream> using std::list; using std::istream; using std::cin; using std::cout; typedef std::vector<char> Line; class Text_Iterator //ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ для класса Document (состоит ΠΈΠ· 2-Ρ… Ρ‡Π»Π΅Π½ΠΎΠ²) { list<Line>::iterator itLine; //строка Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Line::iterator pos; //позиция Π² строкС public: Text_Iterator(list<Line>::iterator ll, Line::iterator pp) { itLine = ll; pos = pp; } Text_Iterator& operator++() { //Ссли pos Π½Π° ΠΊΠΎΠ½Ρ†Π΅ строки Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π½Π° Π½Π°Ρ‡Π°Π»ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ, ΠΈΠ½Π°Ρ‡Π΅ Π½Π° слСд. символ pos if (++pos == itLine->end()) { ++itLine; pos = itLine->begin(); } else ++pos; return *this; }; Text_Iterator& operator--() { //Ссли pos Π² Π½Π°Ρ‡Π°Π»Π΅ строки, Ρ‚ΠΎ становимся Π½Π° ΠΊΠΎΠ½Π΅Ρ† ΠΏΡ€Π΅Π΄. строки, ΠΈΠ½Π°Ρ‡Π΅ --pos if (pos == (itLine->begin())) { itLine--; pos = --(itLine->end()); } else --pos; return *this; }; char& operator*() { return *pos; } bool operator==(const Text_Iterator& arg) const { return (arg.pos == pos); } bool operator!=(const Text_Iterator& arg) const { return !(*this == arg); } //this Π½Π΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, ΠΏΠΎΡ‡Π΅ΠΌΡƒ? }; //класс тСкстового Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° struct Document { list<Line> List; Document() { List.push_back(Line()); } Text_Iterator begin() { return Text_Iterator(List.begin(), List.begin()->begin()); } Text_Iterator end() { list<Line>::iterator end = List.end(); end--; Line::iterator end_pos = end->end(); end_pos--; return Text_Iterator(end, end_pos); } //ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π²Π²ΠΎΠ΄Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° friend istream& operator >> (istream& is, Document& doc) { char input; int i(1); while (is.get(input)) { cout << "#" << i++ << ":" << input << "\n"; doc.List.back().push_back(input); if (input == '\n') //ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ символ ΠΊΠΎΠ½Ρ†Π° doc.List.push_back(Line()); } doc.List.back().push_back('\n');//добавляСм Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ back() return is; } }; 

When I bypass the container in a loop it does not correctly pass! =. I get assert (MSVS 2015) Main.cpp

 int main(int argc, char* argv[]) { Document txt; cin >> txt; for (Text_Iterator it = txt.begin(); it != txt.end(); ++it) { cout << *it; } _getch(); return 0; } 

    3 answers 3

    I think the error is here:

     if (++pos == itLine->end()) { ++itLine; pos = itLine->begin(); } else ++pos; 

    You increment pos twice, as a result of this, pos can become equal to itLine->end() after the second increase.

    Just try

     if (++pos == itLine->end()) { ++itLine; pos = itLine->begin(); } // Π±Π΅Π· else 

      To begin with, I'll point out a typo. In function

       Text_Iterator& operator++() { //Ссли pos Π½Π° ΠΊΠΎΠ½Ρ†Π΅ строки Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π½Π° Π½Π°Ρ‡Π°Π»ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ, ΠΈΠ½Π°Ρ‡Π΅ Π½Π° слСд. символ pos if (++pos == itLine->end()) { ++itLine; pos = itLine->begin(); } else ++pos; return *this; }; 

      a member of the pos class increases twice if the condition in the if expression if not equal to true.

      In addition, you compare only one data member of the pos class Text_Iterator

       bool operator==(const Text_Iterator& arg) const { return (arg.pos == pos); } 

      instead of two: pos and itLine .

      In addition, in the end function, in which I did not find the closing brace

       Text_Iterator end() { list<Line>::iterator end = List.end(); end--; Line::iterator end_pos = end->end(); end_pos--; return Text_Iterator(end, end_pos); } // <=== 

      end_pos variable end_pos not decrease. That is a sentence

        end_pos--; 

      should be removed.

      • Yes, about the first comment is true. - Sergey Ser
      • if not decreasing end_pos, then pos will also point to a non-existent character ... isn't it? - Sergey Ser
      • 2
        @ SergeySer The iterator returned by the end function must point to the last element of the sequence. Otherwise, your program will have undefined behavior. You create an object of the Document class, filling in it an empty vector. Decreasing the iterator for an empty vector leads to undefined program behavior. - Vlad from Moscow
      • And yet left it - Sergey Ser
      • for (Text_Iterator it = doc.begin (); it! = doc.end (); ++ it) os << * it; - Sergey Ser

      In the end, I decided to leave the semantics of the Document.end () method, so that it points to the last character in the container. In this case, it should always be filled in by default, but this is not a good solution ...

      But the loop (below), which seems to be normal, then passes without the iterator going beyond its limits.

       friend ostream& operator << (ostream& os, Document& doc) { for (Text_Iterator it = doc.begin(); it != doc.end(); ++it) os << *it; return os; }