Пишу небольшой редактор текста.
Одна из его компонент должна искать в тексте тэг типа:
{number text1}...{number text2}
далее заменить текст2 текстом1, удалив все специальные символы и собственно полностью {number text1}.
Пример:
{1 abc}
something...
{1 def}
=>
something...
abc
Решил что было бы неплохо сделать список из объектов, которые бы хранили указатели на начало текстов и конец, с номером ("number").
Алгоритм получился примерно такой:
Идём по тексту. Встретили '{'. Создали объект (если вставка сделана не по правилам генерируется исключение). Далее проверили список объектов на наличие объекта с таким номером. Если не нашли, то добавили объект в список. Если нашли - происходит замена (std::string: replace(iterator1,iterator2,inputIt1,inputIt2). Затем удаляется из текста {number text1} и из списка исключается данный объект.
Вопрос такой:
при вызове функции string: replace(), итератор с которым я работал начинает вести себя странным образом. Он перестаёт быть связанным с текстом который я рассматриваю (перестаёт реагировать на условие while(iterator!=text.end()), а уходит за пределы текста.
Я решил это присваивая после вызова функции итератору значение text.begin(). Но однозначно это не самое лучшее решение (потому что получается что каждый раз текст программа просматривает несколько раз).
cutClass.h:
Код:
#ifndef CUTCLASS_H
#define CUTCLASS_H
#include<string>
namespace lab_third{
class t_err{
std::string str;
public:
t_err(std::string s):str(s){}
t_err(const char* s):str(s){}
};
class cutclass{
std::string::iterator begin;
std::string::iterator end;
std::string::iterator sBegin;
int id;
public:
int getId();
cutclass(std::string::iterator,std::string::iterator,std::string::iterator,int);
cutclass(const cutclass&);
std::string::iterator getBegin();
std::string::iterator getsBegin();
std::string::iterator getEnd();
};
void makeAction(std::string&);
}
#endifcutClass.cpp:
Код:
#include"cutClass.h"
#include<list>
#include<iostream>
#include<sstream>
lab_third::cutclass::cutclass(std::string::iterator pBegin,std::string::iterator psBegin,std::string::iterator pEnd,int pId):
begin(pBegin),sBegin(psBegin),end(pEnd),id(pId)
{}
lab_third::cutclass::cutclass(const lab_third::cutclass& cc)
{
begin=cc.begin;
end=cc.end;
sBegin=cc.sBegin;
id=cc.id;
}
int lab_third::cutclass::getId(){
return this->id;
}
std::string::iterator lab_third::cutclass::getBegin(){
return this->begin;
}
std::string::iterator lab_third::cutclass::getsBegin(){
return this->sBegin;
}
std::string::iterator lab_third::cutclass::getEnd(){
return this->end;
}
char search(std::list<lab_third::cutclass>& cutlist,int tId,std::list<lab_third::cutclass>::iterator& iansw);
void cutaction(std::list<lab_third::cutclass>& cutlist,std::string& text,std::string::iterator& itext){
std::cout<<"In cutaction()\n";
std::string::iterator pBegin=itext;
std::cout<<"pBegin is: "<<*pBegin<<"\n";
itext++;
std::string tempId;
while(*itext!=' '){
tempId+=*itext;
if(itext==text.end())
throw(lab_third::t_err("Error"));
itext++;
}//while(*itext!=' ')
std::cout<<"tempId now: "<<tempId<<"\n";
std::istringstream in(tempId);
int tId;
if(!(in >> tId).fail()){
std::cout<<"tId now: "<<tId<<"\n";
std::string::iterator psBegin=++itext;
std::cout<<"psBegin is: "<<*psBegin<<"\n";
while(*itext!='}'){
itext++;
if(itext==text.end())
throw(lab_third::t_err("Error"));
}//while(*itext!='}')
std::cout<<"iterator now on symbol: "<<*itext<<" put in pEnd\n";
std::string::iterator pEnd=itext;
lab_third::cutclass tmpCutObj(pBegin,psBegin,pEnd,tId); // 1)
std::list<lab_third::cutclass>::iterator iansw;
char flag=1;
if(!cutlist.empty()){
flag=search(cutlist,tId,iansw);
}
if(flag==1||cutlist.empty()) // b)
cutlist.push_back(tmpCutObj);
else{ // a)
std::cout<<"In else\n";
std::cout<<text.size()<<"\n";
text.replace(pBegin,++pEnd,iansw->getsBegin(),iansw->getEnd());
std::cout<<text.size()<<"\n";
text.erase(iansw->getBegin(),iansw->getEnd()+1);
std::cout<<text.size()<<"\n";
std::cout<<*pBegin<<"\n";
std::cout<<"Now text:\n"<<text<<"\n";
cutlist.erase(iansw);
itext=text.begin();
std::cout<<"itext now: "<<*itext<<"\n";
}//if(flag)else
}//if(!(in>>tId).fail())
else{
throw(lab_third::t_err("Error"));
}
}//void cutaction()
char search(std::list<lab_third::cutclass>& cutlist,int tId,std::list<lab_third::cutclass>::iterator& iansw){
int size=cutlist.size();
iansw=cutlist.begin();
while(size){
if(iansw->getId()==tId)
return 0;
size--;
if(size)
iansw++;
}
return 1;
}
void lab_third::makeAction(std::string& text){
std::cout<<"in make action!\n";
std::string::iterator itext=text.begin();
std::list<cutclass> cutlist;
while(itext!=text.end()){
std::cout<<"Itext: "<<*itext<<"\n";
if(*itext=='{')
cutaction(cutlist,text,itext);
std::cout<<"Itext: "<<*itext<<"\n";
std::cout<<"text size: "<<text.size()<<"\n";
itext++;
}//while(itext!=text.end())
}//void lab_third::makeAction()
int main(){
std::string text("{1 abc}{1 def}");
std::cout<<text;
try{
lab_third::makeAction(text);
}
catch(lab_third::t_err err){
std::cout<<"in exceptional state!\n";
}
std::cout<<text;
return 0;
}И ещё хотел бы попросить посмотреть код на грамотность написания. Очень буду благодарен за любые замечания/советы.