обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 04.12.01 08:27
Оценка: 18 (2)
Через год с появления первой мысли об унификации этой операции для ANSI и UNICODE строк, наконецто я устал от дублирования кода и создал следующее чудовище:

triml,trimr,trim - понятно что они делают
self_xxx - то же самое что и xxx, только копия не создается

total_xxx - то же самое что и xxx, только обрезаются все символы от '\0' до ' '

Может кому пригодиться ...


///////////////////////////////////////////////////////////////////////////////////

template<class TStr,class TTrimComp>
TStr trimr(const TStr& str,TTrimComp is_trim_char)
{
 TStr::const_iterator i;

 for(i=str.end()-1;
     i>=str.begin() && is_trim_char(*i);
     --i);

 return TStr(str.begin(),++i);
}

template<class TStr,class TTrimComp>
TStr triml(const TStr& str,TTrimComp is_trim_char)
{
 TStr::const_iterator i;

 for(i=str.begin();i!=str.end() && is_trim_char(*i);++i);

 return TStr(i,str.end());
}

template<class TStr,class TTrimComp>
TStr trim(const TStr& str,TTrimComp is_trim_char)
{
 return triml(trimr(str,is_trim_char),is_trim_char);
}

template<class TStr,class TTrimComp>
TStr& self_trimr(TStr& str,TTrimComp is_trim_char)
{
 TStr::iterator i;

 for(i=str.end()-1;
     i>=str.begin() && is_trim_char(*i);
     --i);

 str.erase(++i,str.end());

 return str;
}

template<class TStr,class TTrimComp>
TStr& self_triml(TStr& str,TTrimComp is_trim_char)
{
 TStr::iterator i;

 for(i=str.begin();i!=str.end() && is_trim_char(*i);++i);

 str.erase(str.begin(),i);

 return str;
}

template<class TStr,class TTrimComp>
TStr& self_trim(TStr& str,TTrimComp is_trim_char)
{
 return self_triml(self_trimr(str,is_trim_char),is_trim_char);
}

////////////////////////////////////////////////////////////////////////////////
//trim string functions

//ANSI -------------------------------------------------------------------
inline std::string trimr(const std::string& str)
 {return trimr(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string triml(const std::string& str)
 {return triml(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string trim(const std::string& str)
 {return trim(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string& self_trimr(std::string& str)
 {return self_trimr(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string& self_triml(std::string& str)
 {return self_triml(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string& self_trim(std::string& str)
 {return self_trim(str,std::bind1st(std::equal_to<BYTE>(),BYTE(' ')));}

inline std::string total_trimr(const std::string& str)
 {return trimr(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

inline std::string total_triml(const std::string& str)
 {return triml(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

inline std::string total_trim(const std::string& str)
 {return trim(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

inline std::string& total_self_trimr(std::string& str)
 {return self_trimr(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

inline std::string& total_self_triml(std::string& str)
 {return self_triml(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

inline std::string& total_self_trim(std::string& str)
 {return self_trim(str,std::bind1st(std::greater_equal<BYTE>(),BYTE(' ')));}

//UNICODE ----------------------------------------------------------------
inline std::wstring trimr(const std::wstring& str)
 {return trimr(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring triml(const std::wstring& str)
 {return triml(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring trim(const std::wstring& str)
 {return trim(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring& self_trimr(std::wstring& str)
 {return self_trimr(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring& self_triml(std::wstring& str)
 {return self_triml(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring& self_trim(std::wstring& str)
 {return self_trim(str,std::bind1st(std::equal_to<WCHAR>(),L' '));}

inline std::wstring total_trimr(const std::wstring& str)
 {return trimr(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}

inline std::wstring total_triml(const std::wstring& str)
 {return triml(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}

inline std::wstring total_trim(const std::wstring& str)
 {return trim(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}

inline std::wstring& total_self_trimr(std::wstring& str)
 {return self_trimr(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}

inline std::wstring& total_self_triml(std::wstring& str)
 {return self_triml(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}

inline std::wstring& total_self_trim(std::wstring& str)
 {return self_trim(str,std::bind1st(std::greater_equal<wchar_t>(),L' '));}



27.05.03 10:55: Перенесено из 'C/C++'
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: обрезания строк - достали :)
От: IT Россия linq2db.com
Дата: 04.12.01 15:19
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

КД>Через год с появления первой мысли об унификации этой операции для ANSI и UNICODE строк, наконецто я устал от дублирования кода и создал следующее чудовище:


А у меня ещё вот такое осталось со времён полного господства ANSI. Удаляет всё подряд, в том числе и лишние пробелы из середины.

void TrimAll(char *dest,const char *src) 
{ 
    if (src == 0) src = dest; 
    char *beg = dest; 

    bool wrSpace = *src != ' '; 
    for (; *src; src++) 
        if (*src != ' ')  { *dest++ = *src; wrSpace = true;  }
        else if (wrSpace) { *dest++ = *src; wrSpace = false; } 
    if (beg == dest || wrSpace) *dest = '\0'; 
    else                      *--dest = '\0'; 
}
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 04.12.01 15:43
Оценка:
Доброе утро, IT . Вы писали:

IT>А у меня ещё вот такое осталось со времён полного господства ANSI. Удаляет всё подряд, в том числе и лишние пробелы из середины.


Будем сравнивать?


t_string del_space(const t_string& str,bool all)
{
 t_string result;

 t_string::const_iterator b,i;
 bool skip_space=false;//пропуск пробелов

 i=b=str.begin();

 for(;i!=str.end();i++)
 {
  if(!skip_space)
  {
   if((*i)==_T(' '))
   {
    skip_space=true;
    result.append(b,i+(all?0:1)); //добавляем подстроку (если не all, то включая пробел)
   }
  }
  else //skip_space==true
  if(*i!=_T(' '))
  {
   b=i; //stop skipping
   skip_space=false;
  }
 }//for i

 if(!skip_space)
  result.append(b,i);

 return trim(result);//эээх, нужно self_trim использовать
}
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: обрезания строк - достали :)
От: IT Россия linq2db.com
Дата: 04.12.01 16:00
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

IT>>А у меня ещё вот такое осталось со времён полного господства ANSI. Удаляет всё подряд, в том числе и лишние пробелы из середины.


КД>Будем сравнивать?


Да чё там сравнивать. Вот на MFC всё круче получается:

CString TrimAll(CString s)
{
    s.TrimLeft();
    s.TrimRight();
    while (s.Replace("  "," "));
    return s;
}


Всё прозрачно и очевидно
Если нам не помогут, то мы тоже никого не пощадим.
Re: обрезания строк - достали :)
От: odyssey  
Дата: 04.12.01 16:08
Оценка: 12 (1)
Hi All !
ne pomnu gde otkopal, no uzaetsia

inline
std::string&
TrimLeft(std::string& rString, const char* pWhiteSpace = g_pGenericStringWhiteSpace )
{
rString.erase(0, rString.find_first_not_of(pWhiteSpace));
return rString;
}

inline
std::string&
TrimRight(std::string& rString, const char* pWhiteSpace = g_pGenericStringWhiteSpace )
{
rString.erase( rString.find_last_not_of(pWhiteSpace)+1 );
return rString;
}

inline
std::string&
Trim(std::string& rString, const char* pWhiteSpace = g_pGenericStringWhiteSpace )
{
return TrimRight( TrimLeft(rString, pWhiteSpace), pWhiteSpace );
}


WBR,
odyssey
Re[4]: обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 04.12.01 16:12
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте Коваленко Дмитрий, Вы писали:


IT>>>А у меня ещё вот такое осталось со времён полного господства ANSI. Удаляет всё подряд, в том числе и лишние пробелы из середины.


КД>>Будем сравнивать?


IT>Да чё там сравнивать. Вот на MFC всё круче получается:


IT>
IT>CString TrimAll(CString s)
IT>{
IT>    s.TrimLeft();
IT>    s.TrimRight();
IT>    while (s.Replace("  "," "));
IT>    return s;
IT>}
IT>


IT>Всё прозрачно и очевидно


Пять баллов . Хотя с минусом. Оно же наверняка осуществляет поиск с начала, таким образом обработка строки "1 — тут типа много-много пробелов, которые процессор RSDN вырезает — N" будет выполнять лишние сдвиги хвоста. Обожаю текстовые задачи. Хотя периодически меня на них рвет (где блюющий смайлик? ).
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: обрезания строк - достали :)
От: IT Россия linq2db.com
Дата: 04.12.01 16:21
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

IT>>Всё прозрачно и очевидно


КД>Пять баллов . Хотя с минусом. Оно же наверняка осуществляет поиск с начала, таким образом обработка строки "1 — тут типа много-много пробелов, которые процессор RSDN вырезает — N" будет выполнять лишние сдвиги хвоста.


Ну тут надо выбирать либо эффекивность, либо прозрачность

КД>Обожаю текстовые задачи. Хотя периодически меня на них рвет (где блюющий смайлик? ).


Не, такого смайлика не будет, он не эстетичен и плохо воспринимается моей тонкой натурой
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 04.12.01 16:23
Оценка:
Вообщем, тоже неплохо, но total_trim на этом не построишь :) Да и достало меня впервую очередь отсутствие (в моей же собственной библиотеке) поддержки обрезания UNICODE.

Сколько программистов, столько вариаций решения trim.

Вот интересно сравнить кто как косвенные массивы и массивы объектов со счетчиками ссылок организует. Сразу скажу — во втором случа массив смарт-указателей не котируется.

Все обещал IT'у написать статью — как раз про это дело, но свободного времени в обозримом будующем не предвидится. Ладно, недельки через две, будем искать автора :)
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: обрезания строк - достали :)
От: IT Россия linq2db.com
Дата: 04.12.01 16:51
Оценка: 12 (1)
Здравствуйте odyssey, Вы писали:

O> ne pomnu gde otkopal, no uzaetsia


Здорово, только бы убрать всякую лабуду в виде g_pGenericStringWhiteSpace, убрать лишнюю строчку с return, добавить удаление пробелов внутри и получится:

inline std::string& TrimLeft(std::string& s)
{
    return s.erase(0,s.find_first_not_of(' '));
}

inline std::string& TrimRight(std::string& s)
{
    return s.erase(s.find_last_not_of(' ')+1); 
}

inline std::string& Trim(std::string& s)
{    
    return TrimRight(TrimLeft(s));
}

inline std::string& TrimSelf(std::string& s)
{
    std::string::size_type pos=0;
    while ((pos=s.find("  ",pos)) != std::string::npos)
        s.erase(pos,1);
    return s;
}

inline std::string& TrimAll(std::string& s)
{    
    return TrimSelf(TrimRight(TrimLeft(s)));
}
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: обрезания строк - достали :)
От: dad  
Дата: 07.08.02 13:18
Оценка:
КД>Сколько программистов, столько вариаций решения trim.

может я не совсем уловил суть топика но у меня тоже есть давненько делал:


#ifdef _UNICODE 
  typedef std::wstring btParentString;
#else
  typedef std::string btParentString;  
#endif  


class btString:public btParentString
{    

//poskipano .................

void btString::trimRight(const btString& srs)
{
    size_type pos = npos;
    do
    {
        pos = rfind(srs);
        if (((pos+srs.length()) == length()) && length()>0)
        {
            this->btParentString::erase(pos,srs.size());
        }
        else
        {
            pos = npos;
        }
    }
    while (pos != this->btParentString::npos);
}
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re[4]: обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 07.08.02 13:37
Оценка: 22 (2)
Здравствуйте dad, Вы писали:


КД>>Сколько программистов, столько вариаций решения trim.


dad>может я не совсем уловил суть топика но у меня тоже есть давненько делал:


Однозначно не уловил
Вся фича в том, что в одной программе может быть сразу и ANSI и UNICODE строки, поэтому нужно использовать шаблоны. Ну и раз этот вопрос поднялся наверх, приведу устаканившуюся реализацию обрезателей

это

////////////////////////////////////////////////////////////////////////////////
//service templates for trim operations

template<class TStr,class TTrimComp>
TStr trimr(const TStr& str,TTrimComp is_trim_char)
{
 TStr::const_iterator i;

 for(i=str.end()-1;
     i>=str.begin() && is_trim_char(*i);
     --i);

 return TStr(str.begin(),++i);
}

template<class TStr,class TTrimComp>
TStr triml(const TStr& str,TTrimComp is_trim_char)
{
 TStr::const_iterator i;

 for(i=str.begin();i!=str.end() && is_trim_char(*i);++i);

 return TStr(i,str.end());
}

template<class TStr,class TTrimComp>
TStr trim(const TStr& str,TTrimComp is_trim_char)
{
 TStr t(trimr(str,is_trim_char));

 return self_triml(t,is_trim_char);
}

template<class TStr,class TTrimComp>
TStr& self_trimr(TStr& str,TTrimComp is_trim_char)
{
 TStr::iterator i;

 for(i=str.end()-1;
     i>=str.begin() && is_trim_char(*i);
     --i);

 str.erase(++i,str.end());

 return str;
}

template<class TStr,class TTrimComp>
TStr& self_triml(TStr& str,TTrimComp is_trim_char)
{
 TStr::iterator i;

 for(i=str.begin();i!=str.end() && is_trim_char(*i);++i);

 str.erase(str.begin(),i);

 return str;
}

template<class TStr,class TTrimComp>
TStr& self_trim(TStr& str,TTrimComp is_trim_char)
{
 return self_triml(self_trimr(str,is_trim_char),is_trim_char);
}

////////////////////////////////////////////////////////////////////////////////////
//GENERIC trimXXX                                               ----------
template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 trimr(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return trimr(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 triml(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return triml(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 trim(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return trim(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

//GENERIC self_trimXXX                                          ----------
template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 self_trimr(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_trimr(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 self_triml(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_triml(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 self_trim(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_trim(str,std::bind1st(std::equal_to<_t2::char_comp_type>(),_t2::space()));
 }

//GENERIC total_trimXXX                                         ----------
template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 total_trimr(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return trimr(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 total_triml(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return triml(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>
 total_trim(const std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return trim(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }

//GENERIC total_self_trimXXX                                    ----------
template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 total_self_trimr(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_trimr(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 total_self_triml(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_triml(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }

template<class charT,class traits,class Allocator>
inline std::basic_string<charT,traits,Allocator>&
 total_self_trim(std::basic_string<charT,traits,Allocator>& str)
 {
  typedef t_char_traits2<typename traits::char_type> _t2;
  return self_trim(str,std::bind1st(std::greater_equal<_t2::char_comp_type>(),_t2::space()));
 }
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: обрезания строк - достали :)
От: dad  
Дата: 07.08.02 14:00
Оценка:
КД>>>Сколько программистов, столько вариаций решения trim.

dad>>может я не совсем уловил суть топика но у меня тоже есть давненько делал:


КД>Однозначно не уловил

КД>Вся фича в том, что в одной программе может быть сразу и ANSI и UNICODE строки, поэтому нужно использовать шаблоны.
что то я плохо функциональный код воспринимаю.. а разве нельзя тогда оставить код :



template <class _charT>
class btString:public basic_string<_charT>
{
....
}


КД>Ну и раз этот вопрос поднялся наверх, приведу устаканившуюся реализацию обрезателей

спасибо..
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re[5]: обрезания строк - достали :)
От: dad  
Дата: 09.08.02 16:34
Оценка:
КД>Однозначно не уловил
КД>Вся фича в том, что в одной программе может быть сразу и ANSI и UNICODE строки, поэтому нужно использовать шаблоны. Ну и раз этот вопрос поднялся наверх, приведу устаканившуюся реализацию обрезателей
да уш
есчо бы сюда преобразоание регистра и безрегистровое сравнение .. и было бы замечательно
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re[6]: обрезания строк - достали :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 09.08.02 16:42
Оценка:
Здравствуйте dad, Вы писали:

КД>>Однозначно не уловил

КД>>Вся фича в том, что в одной программе может быть сразу и ANSI и UNICODE строки, поэтому нужно использовать шаблоны. Ну и раз этот вопрос поднялся наверх, приведу устаканившуюся реализацию обрезателей
dad>да уш
dad>есчо бы сюда преобразоание регистра и безрегистровое сравнение .. и было бы замечательно

С этим тоже эпизодически сражаюсь, но пока стратегию не улавливаю
Смутное сомнение, что это можно реализовать согласно стандарту.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[7]: обрезания строк - достали :)
От: dad  
Дата: 09.08.02 16:47
Оценка:
КД>С этим тоже эпизодически сражаюсь, но пока стратегию не улавливаю
КД>Смутное сомнение, что это можно реализовать согласно стандарту.

однако у Вас не только с шаблонами, но и с юмором усе оукей
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Re[5]: обрезания строк - дополнение :)
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 26.05.03 12:02
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Ну и раз этот вопрос поднялся наверх, приведу устаканившуюся реализацию обрезателей


Почитав дядю Мейерса, могу предложить улучшение для шаблонов обрезателей
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.