Conversión de bool a texto en C ++


93

Tal vez esta sea una pregunta tonta, pero ¿hay alguna forma de convertir un valor booleano en una cadena tal que 1 se convierta en "verdadero" y 0 se convierta en "falso"? Podría usar una declaración if, pero sería bueno saber si hay una manera de hacerlo con el lenguaje o las bibliotecas estándar. Además, soy un pedante. :)


6
¡Objeción! ¿Y la localización? ¿Por qué un lenguaje en sí mismo contiene constantes literales específicas del lenguaje?
valdo

1
@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, probablemente se trataba de un proyecto escolar.
Jason Baker

Respuestas:


118

¿Qué tal usar el lenguaje C ++ en 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;

ACTUALIZAR:

Si desea más de 4 líneas de código sin salida de consola, vaya a la página de cppreference.com sobre la que se habla std::boolalphaystd::noboolalpha que muestra la salida de la consola y explica más sobre la API.

Además, el uso std::boolalphamodificará el estado global de std::cout, es posible que desee restaurar el comportamiento original; vaya aquí para obtener más información sobre cómo restaurar el estado destd::cout .


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

4
@Chucky No podrá comprender cómo funciona esto hasta que comprenda la sobrecarga del operador . Explicar cómo funciona eso estaría más allá del alcance de esta pregunta. Deberá publicarlo como una pregunta diferente o buscar las respuestas existentes a esa pregunta. Recomiendo este último .
Michael Dorst

2
Esto solo imprime booleanos como texto, no los convierte en texto / cadena.
atoMerz

Entonces, ¿de qué manera esto falla en el criterio de "convertir un valor booleano en una cadena" dado por el OP?
graham.reeds

2
Este código no convierte un booleano en una cadena. Cree una variable std::string stry guarde el resultado de la conversión en ella, si puede.
rozina

76

Estamos hablando de C ++, ¿verdad? ¿¡Por qué diablos seguimos usando macros !?

Las funciones en línea de C ++ le brindan la misma velocidad que una macro, con el beneficio adicional de seguridad de tipos y evaluación de parámetros (que evita el problema que mencionaron Rodney y dwj.

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

Aparte de eso, tengo algunas otras quejas, particularmente 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;
}

Salud :)


@DrPizza: ¿Incluir una lib de impulso completa por el bien de una función tan simple? ¿Tienes que estar bromeando?


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

Esta es una respuesta problemática, ya que: 1. A veces quieres "sí" o "no" en lugar de "verdadero o" falso ", y otras veces" éxito "frente a" fracaso ", etc. 2. A veces quieres minúsculas, en ocasiones mayúsculas caso, caso de título en algún momento.
einpoklum

2
Lea la pregunta, es exactamente lo que se solicitó.
DO.

@einpoklum Nada le impide crear tantas funciones en línea para las conversiones deseadas como desee.
rozina

2
en una crisis puede hacer:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith

22

C ++ tiene las cadenas adecuadas, por lo que también puede usarlas. Están en la cadena de encabezado estándar. #include <string> para usarlos. No más saturaciones de búfer strcat / strcpy; no más terminadores nulos faltantes; no más gestión de memoria manual desordenada; cadenas contadas adecuadas con semántica de valor adecuada.

C ++ también tiene la capacidad de convertir bools en representaciones legibles por humanos. Vimos sugerencias antes 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 eran unos idiotas completos; también tenemos iostreams que están respaldados no por la consola o un archivo, sino por un búfer de cadena administrado automáticamente. Se llaman cadenas de cadenas. #include <sstream> para obtenerlos. Entonces podemos decir:

std::string bool_as_text(bool b)
{
    std::stringstream converter;
    converter << std::boolalpha << b;   // flag boolalpha calls converter.setf(std::ios_base::boolalpha)
    return converter.str();
}

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

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

Ahora bien, es cierto que se trata de una sobrecarga más alta que alguna macro; Los flujos de cadenas tratan con configuraciones regionales que quizás no le interesen y crean una cadena dinámica (con asignación de memoria) mientras que la macro puede producir una cadena literal, lo que evita eso. Pero, por otro lado, el método stringstream se puede utilizar para una gran cantidad de conversiones entre representaciones imprimibles e internas. Puede ejecutarlos al revés; boost :: lexical_cast <bool> ("true") hace lo correcto, por ejemplo. Puede utilizarlos con números y, de hecho, cualquier tipo con los operadores de E / S formateados correctamente. Por eso 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, es entonces cuando debería considerar hacer algo de macro horror.


3
boost :: lexical_cast <bool> ("true") parece lanzar una excepción bad_lexical_cast
Usuario

3
no funciona en mi aplicación, "isExist:" + boost :: lexical_cast <std :: string> (isSalir)); resultados isExist: 0
Scott 混合 理论

8

Esto debería estar bien:


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

Pero, si quieres hacerlo más 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

Si decide usar macros (o está usando 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")

Ésta es una técnica de programación defensiva que protege contra errores ocultos en el orden de operaciones; es decir, ¿cómo se evalúa esto para todos los compiladores?

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

comparado con

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

Incluso antes de tener una representación de 2k, en realidad podía editar el contenido de otras personas. Será revisado, pero por supuesto que podría hacerlo.
SysDragon

2

Yo uso un ternario en un printf como este:

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

Si lo macro:

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

entonces debe asegurarse de que lo que sea que pase 'b'no tenga efectos secundarios. Y no olvide los corchetes alrededor de, 'b'ya que podría obtener errores de compilación.


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

2

Con C ++ 11, puede usar una lambda para obtener un código un poco más compacto y un uso en el lugar:

bool to_convert{true};
auto bool_to_string = [](bool b) -> std::string {
    return b ? "true" : "false";
};
std::string str{"string to print -> "};
std::cout<<str+bool_to_string(to_convert);

Huellas dactilares:

string to print -> true


1

Sin arrastrar ostream a él:

constexpr char const* to_c_str(bool b) {
   return  
    std::array<char const*, 2>{"false", "true "}[b]
   ;
};


0

¿Qué tal lo simple?

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

-5

Estoy de acuerdo en que una macro podría ser la mejor opción. Acabo de preparar un caso de prueba (créanme que no soy bueno con C / C ++ pero esto sonó 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;
}

-5

Siempre que las cadenas se puedan ver directamente como una matriz de caracteres, será muy difícil convencerme de que std::string representa como ciudadanos de primera clase en C ++.

Además, la combinación de asignación y delimitación me parece una mala idea de todos modos.


-7

Prueba esta macro. En cualquier lugar donde desee que aparezca "verdadero" o falso, reemplácelo con PRINTBOOL (var) donde var es el bool para el que desea el texto.

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

2
Necesita algunos paréntesis en esa macro, que probablemente sea la razón por la que obtuvo el voto negativo.
postfuturista
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.