1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
//
// This is example code from Chapter 20.6.2 "Iteration" of
// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup
//
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
#include<sstream>
#include<fstream>
#include<list>
using namespace std;
//------------------------------------------------------------------------------
typedef vector<char> Line; // a line is a vector of characters
//------------------------------------------------------------------------------
class Text_iterator { // keep track of line and character position within a line
list<Line>::iterator ln;
Line::iterator pos;
public:
typedef forward_iterator_tag iterator_category;
typedef char value_type;
typedef size_t difference_type;
typedef char* pointer;
typedef char& reference;
// start the iterator at line ll's character position pp:
Text_iterator(list<Line>::iterator ll, Line::iterator pp)
:ln(ll), pos(pp) { }
char& operator*() { return *pos; }
list<Line>::iterator getln(){return ln;}
Text_iterator& operator++();
Text_iterator& operator+=(int n);
Text_iterator operator+(int n);
Text_iterator& operator--();
bool operator==(const Text_iterator& other) const;
bool operator!=(const Text_iterator& other) const { return !(*this==other); }
};
//------------------------------------------------------------------------------
Text_iterator& Text_iterator::operator++()
{
if (pos==(*ln).end()) {
++ln; // proceed to next line
pos = (*ln).begin();
}
++pos; // proceed to next character
return *this;
}
Text_iterator& Text_iterator::operator--(){//my operator
if(pos==(*ln).begin()){
--ln;
pos=(*ln).end();
}
--pos;
return *this;
}
Text_iterator& Text_iterator::operator+=(int n){//my opeartor
for(int i=0; i<n; ++i)
++(*this);
return *this;
};
Text_iterator Text_iterator::operator+(int n){//my operator
Text_iterator rvalue=*this;
for(;n>0; --n){
++rvalue;
}
return rvalue;
}
//------------------------------------------------------------------------------
bool Text_iterator::operator==(const Text_iterator& other) const
{
return ln == other.ln && pos == other.pos;
}
//------------------------------------------------------------------------------
struct Document {
list<Line> line;
Document() { line.push_back(Line()); }
Text_iterator begin() // first character of first line
{ return Text_iterator(line.begin(), line.begin()->begin()); }
Text_iterator end() // one beyond the last line
{
list<Line>::iterator last = line.end();
--last;
return Text_iterator(last, last->end());
}
};
//------------------------------------------------------------------------------
void print(Document& d)
{
for (Text_iterator p = d.begin(); p!=d.end(); ++p) cout << *p;
}
//------------------------------------------------------------------------------
template<class Iter> Iter advance(Iter p, int n)
{
while (n>0) { ++p; --n; } // go forwards
return p;
}
//------------------------------------------------------------------------------
void erase_line(Document& d, int n)
{
if (n<0 || d.line.size()<=n) return; // ignore out-of-range lines
d.line.erase(advance(d.line.begin(), n));
}
//------------------------------------------------------------------------------
bool match(Text_iterator first, Text_iterator last, const string& s)
{
string::const_iterator p;
for(p = s.begin();
p != s.end() && first != last && *p == *first;
++p, ++first)
{}
return p == s.end(); // if we reached end of string, we matched it all
}
//------------------------------------------------------------------------------
Text_iterator find_text(Text_iterator first, Text_iterator last, const string& s)
{
if (s.size()==0) return last; // can't find an empty string
char first_char = s[0];
while (true) {
Text_iterator p = find(first,last,first_char);
if (p==last || match(p,last,s)) return p;
}
}
//------------------------------------------------------------------------------
istream& operator>>(istream& is, Document &d){
char c;
while(is.get(c)){
d.line.back().push_back(c);
if(c=='\n'){
d.line.push_back(Line{});
}
}
if(d.line.back().size())d.line.push_back(Line{});
return is;
}
Text_iterator find_replace(Text_iterator first, Text_iterator last, const string& s1, const string& s2){//broke
if(s1.size()==0)return last;
if(s1==s2)return last;
Text_iterator p=last;
while((first=find_text(first,last,s1))!=last){
p=first;
list<Line>::iterator ln=p.getln();
int index=&*p-&(ln->front());
ln->erase(ln->begin()+index,ln->begin()+index+s1.size());//erase
for(int i=0;p!=first+s2.size();++p,++i){
ln->insert(ln->begin()+(&*p-&(ln->front())),s2[i]);//insert
}
}
return p;
}
int main()
{
ifstream ifs{"doc.txt"};
Document my_doc;
while(ifs>>my_doc){}
find_replace(my_doc.begin(),my_doc.end(),"the","xx");
print(my_doc);
}
|