boost :: ifind_first с объектами std :: string - PullRequest
8 голосов
/ 10 августа 2009

Я пытаюсь использовать алгоритмы форсированной строки для поиска без учета регистра.
Всего новичок здесь.

если я использую его таким образом, я получаю сообщение об ошибке.

std::string str1("Hello world");
std::string str2("hello");
if ( boost::ifind_first(str1, str2) ) some code;

Преобразование в указатели на символы разрешает проблему.

boost::ifind_first( (char*)str1.c_str(), (char*)str2.c_str() );

Есть ли способ прямого поиска объектов std :: string?

Кроме того, может быть, есть другой способ узнать, присутствует ли строка внутри другой строки, с поиском без учета регистра?

Ответы [ 3 ]

12 голосов
/ 10 августа 2009

Вам нужно использовать boost :: iterator_range. Это работает:

  typedef const boost::iterator_range<std::string::const_iterator> StringRange;
  std::string str1("Hello world");
  std::string str2("hello");

  if ( boost::ifind_first(
          StringRange(str1.begin(), str1.end()),
          StringRange(str2.begin(), str2.end()) ) )
      std::cout << "Found!" << std::endl;

РЕДАКТИРОВАТЬ: Использование const iterator_range в typedef позволяет передать временный диапазон.

0 голосов
/ 10 августа 2009

(char*)str.c_str() фактически выполняет const_cast: const_cast<char*>(str.c_str()). Я очень серьезно сомневаюсь, что для того, чтобы найти строку, необходимо отбросить const.

Я никогда не использовал boost::ifind_first, но согласно документации функция принимает два диапазона. Я полагаю, есть способ создать диапазон из строки? ОТО, я бы подумал, если бы струна не была идеальным диапазоном.

Может быть полезно, если вы публикуете полные сообщения об ошибках используемого вами компилятора.

0 голосов
/ 10 августа 2009

Примерно так будет выполняться сравнение строк без учета регистра без изменения любой из этих строк.

int nocase_cmp(const string & s1, const string& s2) 
{
  string::const_iterator it1=s1.begin();
  string::const_iterator it2=s2.begin();

  //stop when either string's end has been reached
  while ( (it1!=s1.end()) && (it2!=s2.end()) ) 
  { 
    if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
     // return -1 to indicate smaller than, 1 otherwise
     return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1; 
    //proceed to the next character in each string
    ++it1;
    ++it2;
  }
  size_t size1=s1.size(), size2=s2.size();// cache lengths
  //return -1,0 or 1 according to strings' lengths
  if (size1==size2)  {
    return 0;
  }
  return (size1<size2) ? -1 : 1;
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...