2010-01-29 12 views
38

¿Cuál es la mejor manera de convertir un std :: string en bool? Estoy llamando a una función que devuelve "0" o "1", y necesito una solución limpia para convertir esto en un valor booleano.Conversión de std :: string a bool

Respuesta

29

Probablemente será una exageración para usted, pero me gustaría utilizar boost::lexical_cast

boost::lexical_cast<bool>("1") // returns true 
boost::lexical_cast<bool>("0") // returns false 
+0

Dado que esta solución abarca algunos gastos generales, no debe utilizar esto cuando el rendimiento es importante. O especializa boost :: lexical_cast para tus propias necesidades. – smerlin

+0

Si puede permitirse la conversión de cadenas a bools ... De todos modos, +1: este es el método más sólido hasta el momento. Y si resulta demasiado lento, ¿no sería posible especializar lexical_cast /rogarle a la gente de impulso que lo haga? :) – UncleBens

+2

¿Cómo es esto más robusto que cualquier otra cosa? Su comportamiento no está claro, por ejemplo, los números aleatorios que no sean cero se vuelven verdaderos, "verdadero" y la cadena vacía debe arrojar excepciones. (No estoy seguro.) – Potatoswatter

37
bool to_bool(std::string const& s) { 
    return s != "0"; 
} 
2

escribir una función gratuita:

bool ToBool(const std::string & s) { 
    return s.at(0) == '1'; 
} 

Se trata de la cosa más simple que podría funcionar, pero hay que preguntarse:

  • lo que debe un retorno cadena vacía? la versión anterior arroja una excepción
  • ¿a qué se debe convertir un carácter que no sea '1' o '0'?
  • es una cadena de más de un carácter una entrada válida para la función?

Estoy seguro de que hay otros: ¡esta es la alegría del diseño API!

+0

Este es el mejor método, creo. Usando 'at' ya que el cheque está muy limpio. – GManNickG

+4

@GMan: No estoy seguro de estar de acuerdo con eso. En C, 0 es falso, y todo lo demás es verdadero. Por lo tanto, 2 es verdadero, 03 es verdadero, etc. Por lo tanto, aunque la pregunta esté poco especificada, es razonable suponer que todo lo que no sea cero es verdadero. –

+0

@Chris ¿Qué tal "00"? Mi punto en esta respuesta fue que incluso para una función tan simple, hay muchos problemas que deben ser explorados. –

0

Prueba esto:

bool value; 

if(string == "1") 
    value = true; 
else if(string == "0") 
    value = false; 
+2

Desafortunadamente, esto deja el valor en un estado indeterminado si la cadena debe contener algo más. – UncleBens

+3

@UncleBens: lo más probable es que su valor sea FileNotFound. :-P –

+1

Chris: Me rofl'd. – GManNickG

0
bool to_bool(std::string const &string) { 
    return string[0] == '1'; 
} 
1

que cambiaría la función fea que devuelve esta cadena en el primer lugar. Para eso es Bool.

+0

No tengo control sobre esta función, es una biblioteca de terceros. – cquillen

+0

La biblioteca parece un poco estúpida, sin embargo. ¿Hay alguna razón por la cual debería usar 'std :: string' de todas las cosas para un retorno booleano? – UncleBens

+0

@UncleBens - quizás use std :: string como un tipo de "variante". –

0

Aquí está una manera similar a la de Kyle, excepto en que maneja los ceros a la izquierda y esas cosas:

bool to_bool(std::string const& s) { 
    return atoi(s.c_str()); 
} 
+3

Pero pero ... ¡"DEADBEEF" sería tratado como falso! :-P –

+0

¿Y por qué sería cierto? –

+0

@Andreas: La tradición C es que 0 es falso, y todo lo demás es verdadero. Idealmente, me gustaría lanzar una excepción en ese caso, pero si eso no es una opción, entonces true es "menos incorrecto" que falso, en mi opinión. –

2

I' Use esto, que hace lo que quiere, y capta el caso de error.

bool to_bool(const std::string& x) { 
    assert(x == "0" || x == "1"); 
    return x == "1"; 
} 
0

siempre se puede envolver la cadena devuelta en una clase que maneja el concepto de cadenas booleanas:

class BoolString : public string 
{ 
public: 
    BoolString(string const &s) 
    : string(s) 
    { 
     if (s != "0" && s != "1") 
     { 
      throw invalid_argument(s); 
     } 
    } 

    operator bool() 
    { 
     return *this == "1"; 
    } 
} 

llamada algo como esto:

BoolString bs(func_that_returns_string()); 
if (bs) ...; 
else ...; 

Qué va a lanzar invalid_argument si el regla sobre "0" y "1" se viola.

+1

No todo tiene que ser una clase; una función libre es mucho más limpia y segura. – GManNickG

+0

@GMan, yo sería el primero en decir eso :) –

9

O le importa la posibilidad de un valor de retorno no válido o no. La mayoría de las respuestas hasta ahora están en el medio, atrapando algunas cuerdas además de "0" y "1", quizás racionalizando cómo deberían convertirse, quizás lanzando una excepción. La entrada no válida no puede producir resultados válidos, y no debe intentar aceptarlos.

Si no le importan las devoluciones no válidas, use s[0] == '1'. Es súper simple y obvio. Si debe justificar su tolerancia a alguien, digamos que convierte la entrada no válida en falsa, y la cadena vacía es probable que sea un solo \0 en su implementación de STL, por lo que es razonablemente estable. s == "1" también es bueno, pero s != "0" me parece obtuso y no válido => verdadero.

Si no se preocupan por los errores (y probablemente debería), utilice

if (s.size() != 1 
|| s[0] < '0' || s[0] > '1') throw input_exception(); 
b = (s[0] == '1'); 

Esto llama todos los errores, también sin rodeos obvio y simple para cualquiera que conozca un poquito de C, y nada va a realizar más rápido .

61

me sorprende que nadie mencionó éste:

bool b; 
istringstream("1") >> b; 

o

bool b; 
istringstream("true") >> std::boolalpha >> b; 
+2

La reputación no siempre va con la respuesta superior (imho). :) – gsamaras

+0

¡Agradable! Esto funcionó para mí usando la API Lua C.Supongo que C no tiene un tipo de datos booleanos ; lua_toboolean() devuelve un valor int de 0 o 1, por lo que parece hacer el truco en C++. – Artorias2718

+0

Sí, es secuencias de C++ https://www.cprogramming.com/tutorial/c++-iostreams.html. –

5

Existe también std :: Stoi en C++ 11:

valor bool = std :: stoi (someString.c_str());

Cuestiones relacionadas