2009-08-10 12 views
8

Estoy tratando de usar algoritmos de cadena de refuerzo para la búsqueda insensible a mayúsculas y minúsculas.
total de principiantes aquí.boost :: ifind_first con std :: string objects

si lo estoy utilizando de esta manera, me sale un error.

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

Convirtiendo en char punteros resuelve el problema.

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

¿Hay alguna manera de buscar objetos std :: string directamente?

Además, tal vez haya otra forma de saber si la cadena está presente dentro de otra cadena con búsqueda insensible a mayúsculas y minúsculas.

Respuesta

12

Debe usar boost :: iterator_range. Esto funciona:

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; 

EDITAR: Usar un iterador_range en el typedef permite pasar un rango temporal.

+0

El primer argumento de ifind_first() es Range1T &. No es estándar pasar un rango temporal. –

+0

@ DanielLaügt: 'Range1T' se deducirá como' const boost :: iterator_range ', lo que da como resultado una referencia constante. ¿Tienes un problema al pasar una referencia constante a un temporal? –

+0

No he visto la const antes iterator_range. Esto funciona bien No sabía que podemos hacer este tipo de truco. He aprendido algo Gracias. –

0

Algo así hará una comparación de cadenas sin diferencias entre mayúsculas y minúsculas sin modificar ninguna cadena.

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

(char*)str.c_str() actual ejercicio de una const_cast: const_cast<char*>(str.c_str()). Dudo seriamente que sea necesario descartar const para buscar a través de la cadena.

Nunca he usado boost::ifind_first, pero según el documentation, la función ocupa dos rangos. ¿Supongo que hay una manera de crear un rango a partir de una cuerda? OTOH, me pregunto si una cuerda no es un rango perfecto.

Puede ser útil si publica los mensajes de error completos del compilador que utilizó.

Cuestiones relacionadas