2010-08-31 26 views
21

Actualmente estoy leyendo un archivo ini con un par clave/valor. es decir,C++ std :: string to boolean

isValid = true 

Cuando conseguir el par clave/valor que necesito para convertir una cadena de 'verdadero' a un bool. Sin usar boost, ¿cuál sería la mejor manera de hacer esto?

Sé que puedo comparar una cadena en el valor ("true", "false"), pero me gustaría hacer la conversión sin tener la cadena en el archivo ini mayúsculas y minúsculas.

Gracias

Respuesta

29

Otra solución sería utilizar tolower() para obtener una versión en minúsculas de la cadena y luego comparar o usar cadenas de transmisión:

#include <sstream> 
#include <string> 
#include <iomanip> 
#include <algorithm> 
#include <cctype> 

bool to_bool(std::string str) { 
    std::transform(str.begin(), str.end(), str.begin(), ::tolower); 
    std::istringstream is(str); 
    bool b; 
    is >> std::boolalpha >> b; 
    return b; 
} 

// ... 
bool b = to_bool("tRuE"); 
+1

+1 buena respuesta + otro 1 porque no sabía sobre boolalpha. Tenga en cuenta que boost :: lexical_cast (que hace lo mismo) no es muy indulgente con el caso, ya sea – pm100

+0

esto es realmente genial ... No estaba al tanto de 'std :: boolalpha' – rmeador

+0

Intenté usar esto pero está diciendo que transform no es parte de std. Incluí ¿Qué extrañé? – Wesley

0

Si no puede utilizar impulso, tratar strcasecmp:

#include <cstring> 

std::string value = "TrUe"; 

bool isTrue = (strcasecmp("true",value.c_str()) == 0); 
+0

'strcasecmp' no existe en Windows. – zneak

+1

¡Oh, vamos! Parece que un Boost es la única forma de comparar cadenas :-) Hay formas mucho más fáciles y eficientes que hacer un reparto léxico, realmente. Especialmente cuando sabe exactamente lo que está haciendo y no está creando una biblioteca de conversión de todo uso para todo en uno. –

+0

@zneak - Windows tiene "stricmp" (http://msdn.microsoft.com/en-us/library/k59z8dwe%28v=VS.80%29.aspx) –

0

Minúsculas la cadena iterando la cadena y llama a tolower en los carachters, luego compararla con "true" o "false", si la carcasa es su única preocupación.

for (std::string::iterator iter = myString.begin(); iter != myString.end(); iter++) 
    *iter = tolower(*iter); 
+0

tolower() funciona en un solo carácter, c_str() devuelve un puntero a una cadena que no se debe modificar. Así que esta idea sería realmente dañina. –

+0

@Uli Schlanchter ¿De dónde saqué la idea de que funcionó en las cuerdas? Gracias por la captura. – zneak

2
#include <string> 
#include <strings.h> 
#include <cstdlib> 
#include <iostream> 

bool 
string2bool (const std::string & v) 
{ 
    return !v.empty() && 
     (strcasecmp (v.c_str(), "true") == 0 || 
     atoi (v.c_str()) != 0); 
} 

int 
main() 
{ 
    std::string s; 
    std::cout << "Please enter string: " << std::flush; 
    std::cin >> s; 
    std::cout << "This is " << (string2bool (s) ? "true" : "false") << std::endl; 
} 

Una entrada de ejemplo y de salida:

$ ./test 
Please enter string: 0 
This is false 
$ ./test 
Please enter string: 1 
This is true 
$ ./test 
Please enter string: 3 
This is true 
$ ./test 
Please enter string: TRuE 
This is true 
$ 
+0

'strcasecmp' no es portátil. Algunas plataformas usan 'stricmp', extrañamente. – greyfade