9
votes

Boost :: ifind_first avec std :: Objets de chaîne

J'essaie d'utiliser des algorithmes de string de boost pour une recherche insensible à casse.
Total Newbie ici.

Si je l'utilise de cette façon, je reçois une erreur. p>

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


0 commentaires

3 Réponses :


0
votes

Quelque chose comme ça va faire une comparaison de cas insensible aux chaînes sans modifier ni la chaîne.

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;
}


0 commentaires

0
votes

(char *) str.c_str () effectue réellement un const_cast : const_cast (str.c_str ()) . Je doute très sérieusement qu'il soit nécessaire de jeter const afin de rechercher dans la chaîne.

Je n'ai jamais utilisé boost :: ifind_first , mais selon le Documentation , la fonction prend deux gammes. Je suppose qu'il y a un moyen de créer une gamme d'une chaîne? OTOH, je me demanderais si une chaîne n'était pas une gamme parfaite.

Il peut être utile de poster les messages d'erreur complètes du compilateur que vous avez utilisé.


0 commentaires

13
votes

Vous devez utiliser Boost :: iterator_range. Cela fonctionne:

  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;


5 commentaires

Le premier argument de ifind_first () est Gamme1T &. Il n'est pas standard de passer une plage temporaire.


@ Daniellaügt: range1t sera déduit à être const boost :: iterator_range , entraînant une référence de const. Vous avez un problème de transmission d'une référence constante à un temporaire?


Je n'ai pas vu le const avant iterator_range. Cela fonctionne bien. Je ne savais pas que nous pouvons faire ce genre d'astuce. J'ai appris quelque chose. Merci.


Cependant, cela ne compile pas sur l'option MSVC avec / ZA. Probablement un bug dans le compilateur Microsoft car il compile une amende sur GCC et CLANG ...


Je reçois une erreur C2440: 'static_cast': impossible de convertir de 'std_cordst_berator <_elem, _traits, _alloc>' to 'std :: _ string_iterator <_elem, _traits, _ALLOC>' Avec ce code dans VS2010.