2008-08-27 12 views
65

Quizás esta es una pregunta tonta, pero ¿hay alguna forma de convertir un valor booleano en una cadena de modo que 1 cambie a "verdadero" y 0 a "falso"? Podría usar una declaración if, pero sería bueno saber si hay una forma de hacerlo con el lenguaje o las bibliotecas estándar. Además, soy un pedante. :)Convirtiendo bool a texto en C++

+4

Objeción! ¿Qué pasa con la localización? ¿Por qué un lenguaje en sí mismo contiene constantes literales específicas del lenguaje? – valdo

+0

@valdo - Estoy bastante seguro de que para el proyecto en el que estaba trabajando, la internacionalización no era una preocupación. En ese momento, era probable que fuera un proyecto escolar. –

Respuesta

99

Cómo sobre el uso del lenguaje C++ sí?

bool t = true; 
bool f = false; 
std::cout << std::noboolalpha << t << " == " << std::boolalpha << t << std::endl;   
std::cout << std::noboolalpha << f << " == " << std::boolalpha << f << std::endl; 
+0

Soy un completo novato en C++. ¿Alguien puede explicarme cómo funciona esto? – Chucky

+3

@Chucky No podrá entender cómo funciona esto hasta que comprenda [sobrecarga del operador] (http://stackoverflow.com/questions/4421706/operator-overloading). Explicar cómo funciona eso estaría más allá del alcance de esta pregunta. Deberá publicarlo como una pregunta diferente o buscar respuestas existentes a esa pregunta. [Recomiendo esta última] (http://mattgemmell.com/2008/12/08/what-have-you-tried/). – anthropomorphic

+1

Fairplay supongo. – Chucky

-5

Estoy de acuerdo en que una macro podría ser la mejor opción. Yo sólo prepararon rápidamente un caso de prueba (créanme que no soy bueno con C/C++, pero esto sonaba divertido):

#include <stdio.h> 
#include <stdarg.h> 

#define BOOL_STR(b) (b?"true":"false") 

int main (int argc, char const *argv[]) { 
    bool alpha = true; 
    printf(BOOL_STR(alpha)); 
    return 0; 
} 
-7

probar este macro. En cualquier lugar donde desee que aparezca "verdadero" o falso simplemente reemplácelo por PRINTBOOL (var) donde var es el bool para el que desea el texto.

#define PRINTBOOL(x) x?"true":"false" 
+0

Necesita algunos paréntesis en esa macro, que es probablemente la razón por la que obtuvo el voto a favor. – postfuturist

1

Puedo usar un ternaria en un printf así:

printf("%s\n", b?"true":"false"); 

Si macro que:

B2S(b) ((b)?"true":"false") 

entonces usted necesita para asegurarse de que todo lo que pasa en tan 'b' doesn' Tiene cualquier efecto secundario. Y no olvide los corchetes alrededor del 'b' ya que podría obtener errores de compilación.

+0

Como 'b' solo aparece una vez en la definición de macro, ¿por qué advierte de los efectos secundarios? – postfuturist

4

Si decide usar macros (o usa C en un proyecto futuro) debe agregar paréntesis alrededor de la 'b' en la expansión de macro (todavía no tengo suficientes puntos para editar el contenido de otras personas):

#define BOOL_STR(b) ((b)?"true":"false") 

Esta es una técnica defensive programming que protege contra errores ocultos de orden de operaciones; es decir, ¿cómo se evalúa esto para todos los compiladores?

1 == 2 ? "true" : "false" 

en comparación con

(1 == 2) ? "true" : "false" 
+0

Incluso antes de tener el representante de 2k, en realidad podría editar el contenido de otras personas.Será revisado, pero por supuesto que podrías. – SysDragon

59

Estamos hablando de C++ ¿no? ¿Por qué demonios seguimos usando macros?

C funciones en línea ++ darle la misma velocidad que una macro, con el beneficio añadido de seguridad de tipos y evaluación de parámetros (que evita el problema que Rodney y dwj mencionado.

inline const char * const BoolToString(bool b) 
{ 
    return b ? "true" : "false"; 
} 

Aparte de que tengo algunas otras quejas, en particular con la respuesta aceptada :)

// this is used in C, not C++. if you want to use printf, instead include <cstdio> 
//#include <stdio.h> 
// instead you should use the iostream libs 
#include <iostream> 

// not only is this a C include, it's totally unnecessary! 
//#include <stdarg.h> 

// Macros - not type-safe, has side-effects. Use inline functions instead 
//#define BOOL_STR(b) (b?"true":"false") 
inline const char * const BoolToString(bool b) 
{ 
    return b ? "true" : "false"; 
} 

int main (int argc, char const *argv[]) { 
    bool alpha = true; 

    // printf? that's C, not C++ 
    //printf(BOOL_STR(alpha)); 
    // use the iostream functionality 
    std::cout << BoolToString(alpha); 
    return 0; 
} 

Saludos :)


@DrPizza: ¿Incluir un lib completo de impulso por el bien de una función así de simple? ¿Tienes que estar bromeando?

+1

¿Qué hay de malo en la respuesta aceptada? –

+5

Nada está mal con la respuesta aceptada. –

+0

@NathanFellman, la respuesta aceptada es demasiado lenta. Este se puede mejorar para 'cadena' si las constantes de cadena para" verdadero "y" falso "se almacenan en variables constantes estáticas. –

21

Jesús lloró.

Bien, usted ha preguntado acerca de C++. No C. No frigging macros. C++.

C++ tiene las cuerdas adecuadas. No es la estúpida tontería de NTBS. Cuerdas apropiadas ¡Usalos, usalos a ellos! Están en la cadena de encabezado estándar. #include <cadena> para usarlos. No más desbordamientos de buffer strcat/strcpy; ya no faltan terminadores nulos; no más administración desordenada de la memoria manual; cadenas contadas apropiadas con semántica de valor apropiado.

C++ tiene la capacidad de convertir bools en representaciones legibles para humanos también. Vimos sugerencias anteriores con los ejemplos de iostream, pero son un poco limitados porque solo pueden enviar el texto a la consola (o con fstreams, un archivo). Afortunadamente, los diseñadores de C++ no fueron completos idiotas; también tenemos iostreams que están respaldados no por la consola o un archivo, sino por un buffer de cadena gestionado automáticamente. Se llaman cadenas de transmisión. #include <sstream> para obtenerlos. Entonces podemos decir:

std::string bool_as_text(bool b) 
{ 
    std::stringstream converter; 
    converter << b; 
    return converter.str(); 
} 

Por supuesto, realmente no queremos escribir todo eso. Afortunadamente, C++ también tiene una conveniente biblioteca de terceros llamada Boost que nos puede ayudar aquí. Boost tiene una función agradable llamada lexical_cast. Podemos usar así:

boost::lexical_cast<std::string>(my_bool) 

Ahora, es cierto que este es más alto por encima de lo que algunos macro; las cadenas de caracteres se relacionan con las configuraciones regionales que no le interesan, y crean una cadena dinámica (con asignación de memoria) mientras que la macro puede producir una cadena literal, lo cual evita eso. Pero por otro lado, el método de cadena de caracteres se puede utilizar para una gran cantidad de conversiones entre representaciones imprimibles e internas. Puedes ejecutarlos hacia atrás; boost :: lexical_cast <bool> ("true") hace lo correcto, por ejemplo. Puede usarlos con números y de hecho cualquier tipo con los operadores de E/S formateados correctos. Entonces son bastante versátiles y útiles.

Y si después de todo esto su perfil y evaluación comparativa revela que los lexical_casts son un cuello de botella inaceptable, que es cuando debería considerar hacer algo de macro horror.

+3

boost :: lexical_cast ("true") parece lanzar una excepción bad_lexical_cast – User

+2

no funciona en mi aplicación, "isExist:" + boost :: lexical_cast (isExit)); results isExist: 0 –

6

Esto debe estar bien:


const char* bool_cast(const bool b) { 
    return b ? "true" : "false"; 
} 

Pero, si desea hacerlo más a C++ - ish:


#include <iostream> 
#include <string> 
#include <sstream> 
using namespace std; 

string bool_cast(const bool b) { 
    ostringstream ss; 
    ss << boolalpha << b; 
    return ss.str(); 
} 

int main() { 
    cout << bool_cast(true) << "\n"; 
    cout << bool_cast(false) << "\n"; 
} 
-5

Mientras cuerdas se pueden ver directamente como una matriz de caracteres que va ser realmente difícil convencerme de que std::string representa cadenas como ciudadanos de primera clase en C++.

Además, combinar la asignación y la delimitación parece ser una mala idea para mí de todos modos.