string.find () devuelve verdadero cuando se usa == – 1 pero falso cuando se usa <0

Estoy tratando de encontrar un personaje dentro de una cadena pero estoy obteniendo resultados inesperados. Mi entendimiento es que string::find(char c) devuelve -1 cuando no se encuentra. Sin embargo, estoy obteniendo algunos resultados inesperados.

Aunque la cadena no incluye un '8' , sigue devolviendo true .

 std::string s = "123456799"; if(s.find('8')<0) cout << "Not Found" << endl; else cout << "Found" << endl; //Output: Found 

Sin embargo, cuando se usa == el código funciona como se esperaba.

 std::string s = "123456799"; if(s.find('8')==-1) cout << "Not Found" << endl; else cout << "Found" << endl; //Output: Not Found 

Mi entendimiento es que string::find(char c) devuelve -1 cuando no se encuentra.

No es exacto Según la documentación :

Valor de retorno
Posición del primer carácter de la subcadena o npos encontrada si no se encuentra dicha subcadena.

Entonces, para ser precisos, cuando no se encuentre, std::string::find devolverá std :: string :: npos . El punto es que el tipo de std::string::npos es std::string::size_type , que es un tipo entero sin signo. Incluso se inicializa a partir del valor de -1 , no es -1 ; todavía está sin firmar. Así que s.find('8')<0 siempre será false porque no es posible ser negativo.

Documentación de std :: string :: npos :

 static const size_type npos = -1; 

Este es un valor especial igual al valor máximo representable por el tipo size_type .

Por lo tanto, debe usar std :: string :: npos para verificar el resultado, para evitar este tipo de confusión.

 if (s.find('8') == std::string::npos) cout << "Not Found" << endl; else cout << "Found" << endl; 

if(s.find('8')==-1) funciona bien, porque el operando de la izquierda del operador == aquí no está firmado, el de la derecha está firmado. De acuerdo con las reglas para los operadores aritméticos ,

  • De lo contrario, si el rango de conversión del operando sin firmar es mayor o igual al rango de conversión del operando firmado, el operando firmado se convierte al tipo de operando sin signo.

Por lo tanto, -1 se convertirá en unsigned, que es el valor de std::string::npos y luego todo funcionará como se espera.

string::find() devuelve size_t , que es un int sin signo por lo que nunca puede ser negativo.