2012-02-20 8 views
5

Tengo un búfer (por ejemplo, char buffer[1024]) que se llena con algunos datos. Ahora quiero buscar una subcadena en este búfer. Como debería ser una búsqueda insensata de caso, estoy usando boost::algorithm::ifind_first.Boost find_first ¿cómo funciona?/Definir un rango

Así que llame a la función como esta:

boost::iterator_range<char*> buf_iterator; 
buf_iterator = boost::algorithm::ifind_first(buffer ,"substring"); 

En realidad, esto funciona bien. Pero mi preocupación es la siguiente:

Paso la función solo a char pointer, por lo que ifind_first no debería tener idea de dónde termina mi búfer, pero aún funciona.

Ahora mi primera idea fue que la función busca hasta un carácter de terminación de cadena. Pero en el Boost Documentation la función se define de esta manera:

template<typename Range1T, typename Range2T> 
    iterator_range< typename range_iterator<Range1T>::type > 
    find_first(Range1T & Input, const Range2T & Search); 

ya que trabaja con los parámetros de plantilla que realmente duda de que se está trabajando con terminación nula?

Así que mi pregunta es ¿cómo sabe ifind_first dónde parar? O para ser más precisos, ¿cómo puedo darle un rango? Como ya se mencionó, funciona bien con un char*, pero no estoy seguro de si no tuve suerte, es decir, en el peor de los casos se llama a la función y no sabe dónde parar y entra en la memoria indefinida. .

Editar:

Ahora en una respuesta no había mencionado que depende del tipo que pase a la función. Ahora, ¿esto significaría que si trabajo con un buffer char siempre tengo que asegurarme de que esté terminado por 0 ...?

+0

Si los documentos indican el método, está muy bien escondido. – CapelliC

+0

Por favor, no firme sus publicaciones. –

Respuesta

5

Se utiliza una técnica en la que la longitud de una matriz es un argumento de plantilla, es decir:

template< typename T, size_t L > 
void foo(T (&arr)[L]) 
{ 
} 

como una cadena literal ha conocido longitud L puede ser deducido, como foo ("test") siendo foo < char, 5>(). Apuesto a que hay una sobrecarga para const char * donde se supone que el argumento es una cadena c, donde strlen() se puede usar para determinar la longitud.

EDIT: Una mejor explicación de cómo la demostración ifind_first se producirá un error, y por qué no se si usted tiene cuidado

Lo que decide si ifind_first fallará o no en este caso es si bien sujeto o degenera en la búsqueda un char *. En este caso, ha pasado un literal de cadena como la búsqueda directamente, ifind_first lo intentará y supondrá que concluirá que es const char [10] (longitud de "substring" + 1 para NULL terminator). Sin embargo, para la búsqueda no importa, porque incluso si degenera en const char * ifind_first adivinará que es una cadena c terminada NULL, y una cadena literal es una cadena c terminada NULL y por lo tanto funciona dandy.

En este caso, realmente está pidiendo buffer char [1024], en su caso no degenera a char *. Pero si en cambio hubieras tenido permiso para decir char * buffer = new char [1024]; el tipo de búfer es char * y no está garantizado que tenga terminación NULL. En este caso ifind_first fallará de maneras misteriosas dependiendo de lo que haya detrás del área que ha llenado.

Por lo tanto, como el tipo de buffer es char [1024] en su caso, no tocará la memoria más allá del final del buffer, PERO, tampoco le importará si hay un terminador NULL allí (no lo busca, ya que lo ha pasado un char [1024] conoce la longitud en tiempo de compilación). Entonces, si digamos que llenas el buffer con 12 caracteres seguidos de NULL, buscará todo el buffer.

+0

Esto no explica por qué parece funcionar con un búfer 'char' terminado no nulo, donde 'strlen()' no ayudará. – nabulke

+0

Eso significa, por ejemplo: si tengo un búfer con 1024 Bytes, debería inicializar mi búfer con 'char buffer [1025] = {0}', así que me aseguro de que ** siempre ** nulo termine (incluso cuando reciba exactamente 1024 bytes) ...? – Toby

+0

@nabulke: No, el búfer de char [1024] tiene un tamaño fijo, no es char * (aunque puede degenerar en char * si no tiene cuidado). Pruebe buf_iterator = boost :: algorithm :: ifind_first ((char *) buffer, "substring"); – Ylisar