Convertendo bool em texto em C ++

93

Talvez esta seja uma pergunta idiota, mas há alguma maneira de converter um valor booleano em uma string de forma que 1 se transforme em "verdadeiro" e 0 em "falso"? Eu poderia apenas usar uma instrução if, mas seria bom saber se existe uma maneira de fazer isso com a linguagem ou bibliotecas padrão. Além disso, sou um pedante. :)

Jason Baker
fonte
6
Objeção! E a localização? Por que uma linguagem em si conteria constantes literais específicas da linguagem?
valdo
1
@valdo - Tenho quase certeza de que para o projeto em que estava trabalhando a internacionalização não era uma preocupação. Na época, provavelmente era um projeto escolar.
Jason Baker

Respostas:

118

Que tal usar a própria linguagem C ++?

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;

ATUALIZAR:

Se você quiser mais de 4 linhas de código sem nenhuma saída do console, vá para a página cppreference.com falando sobre std::boolalphaestd::noboolalpha que mostra a saída do console e explica mais sobre a API.

Além disso, o uso de std::boolalphairá modificar o estado global de std::cout, você pode querer restaurar o comportamento original vá aqui para obter mais informações sobre como restaurar o estado destd::cout .

graham.reeds
fonte
Sou um novato completo em C ++. Alguém pode me explicar como isso funciona?
Chucky de
4
@Chucky Você não será capaz de entender como isso funciona até entender a sobrecarga do operador . Explicar como isso funciona está muito além do escopo desta pergunta. Você precisará postá-la como uma pergunta diferente ou procurar as respostas existentes para essa pergunta. Eu recomendo o último .
Michael Dorst,
2
Isso só imprime booleanos como texto, não os converte em texto / string.
atoMerz
Então, de que forma isso falha no critério de "converter um valor booleano em uma string" fornecido pelo OP?
graham.reeds
2
Este código não converte um booleano em uma string. Crie uma variável std::string stre salve o resultado da conversão nela, se puder.
rozina
76

Estamos falando sobre C ++ certo? Por que diabos ainda estamos usando macros !?

As funções embutidas do C ++ oferecem a mesma velocidade de uma macro, com o benefício adicional de segurança de tipo e avaliação de parâmetro (o que evita o problema mencionado por Rodney e dwj.

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

Além disso, tenho algumas outras queixas, principalmente com a resposta aceita :)

// 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;
}

Felicidades :)


@DrPizza: Incluir uma biblioteca completa de boost por causa de uma função tão simples? Você só pode estar brincando?

OJ.
fonte
@NathanFellman, a resposta aceita é muito lenta. Isso pode ser melhorado stringse as constantes de string para "true" e "false" forem armazenadas em variáveis ​​const estáticas.
Serge Rogatch
Esta é uma resposta problemática, pois: 1. Às vezes você quer "sim" ou "não" em vez de "verdadeiro ou" falso ", e às vezes" sucesso "vs" falha "etc. 2. Às vezes você quer minúsculas, outras vezes maiúsculas caso, em algum momento caso de título.
einpoklum
2
Leia a pergunta, é exatamente o que foi solicitado.
OJ.
@einpoklum Nada o impede de criar quantas funções inline para as conversões desejadas você deseja.
rozina
2
em uma crise você pode fazer:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith
22

C ++ tem strings adequadas, então você também pode usá-las. Eles estão na string de cabeçalho padrão. #include <string> para usá-los. Chega de estouros de buffer strcat / strcpy; não há mais terminadores nulos ausentes; não há mais gerenciamento de memória manual confuso; strings contadas corretamente com semântica de valor adequada.

C ++ tem a capacidade de converter bools em representações legíveis por humanos também. Vimos dicas sobre isso antes com os exemplos do iostream, mas eles são um pouco limitados porque só podem enviar o texto para o console (ou com fstreams, um arquivo). Felizmente, os designers do C ++ não eram idiotas completos; também temos iostreams que são apoiados não pelo console ou um arquivo, mas por um buffer de string gerenciado automaticamente. Eles são chamados de streams. #include <sstream> para obtê-los. Então podemos dizer:

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();
}

Claro, não queremos digitar tudo isso. Felizmente, C ++ também tem uma biblioteca de terceiros conveniente chamada Boost que pode nos ajudar aqui. Boost tem uma função legal chamada lexical_cast. Podemos usá-lo assim:

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

Agora, é verdade que essa sobrecarga é mais alta do que alguma macro; stringstreams lidam com locais com os quais você pode não se importar e criam uma string dinâmica (com alocação de memória), enquanto a macro pode gerar uma string literal, o que evita isso. Mas, por outro lado, o método stringstream pode ser usado para muitas conversões entre representações imprimíveis e internas. Você pode executá-los ao contrário; boost :: lexical_cast <bool> ("true") faz a coisa certa, por exemplo. Você pode usá-los com números e, na verdade, qualquer tipo com os operadores de E / S formatados corretamente. Portanto, eles são bastante versáteis e úteis.

E se depois de tudo isso seu perfil e benchmarking revelarem que os lexical_casts são um gargalo inaceitável, é quando você deve considerar fazer algum terror macro.

DrPizza
fonte
3
boost :: lexical_cast <bool> ("true") parece lançar uma exceção bad_lexical_cast
Usuário de
3
não funciona em meu aplicativo, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); resultados isExist: 0
Scott 混合 理论
7

Isso deve estar bem:


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

Mas, se você quiser fazer mais 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";
}
Shadow2531
fonte
5

Se você decidir usar macros (ou estiver usando C em um projeto futuro), deve adicionar parênteses ao redor de 'b' na expansão da macro (ainda não tenho pontos suficientes para editar o conteúdo de outras pessoas):

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

Esta é uma técnica de programação defensiva que protege contra erros ocultos de ordem de operações; ou seja, como isso é avaliado para todos os compiladores?

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

comparado com

(1 == 2) ? "true" : "false"
dwj
fonte
Mesmo antes de ter um representante de 2k você pode editar o conteúdo de outras pessoas. Ele será revisado, mas é claro que você poderá.
SysDragon
2

Eu uso um ternário em um printf assim:

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

Se você macro:

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

então você precisa ter certeza de que tudo o que você passa 'b'não tem efeitos colaterais. E não se esqueça dos colchetes ao redor do, 'b'pois você pode obter erros de compilação.

Nathan Fellman
fonte
Como 'b' só aparece uma vez na definição da macro, por que você está avisando sobre os efeitos colaterais?
postfuturist
2

Com C ++ 11, você pode usar um lambda para obter um código um pouco mais compacto e uso local:

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);

Impressões:

string to print -> true
Federico Spinelli
fonte
1

Este post é antigo, mas agora você pode usar std::to_stringpara converter muitas variáveis ​​como std::string.

http://en.cppreference.com/w/cpp/string/basic_string/to_string

Erwan Guiomar
fonte
Você pode, mas se fizer isso em uma variável bool, ela apenas converterá o valor numérico, "1" ou "0", em vez de "verdadeiro" ou "falso".
David E
1

Sem arrastar ostream para ele:

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

Use boolalphapara imprimir o bool em string.

std::cout << std::boolalpha << b << endl;
std::cout << std::noboolalpha << b << endl;

Referência C ++

UIResponder
fonte
0

Que tal o simples:

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

Concordo que uma macro pode ser o melhor ajuste. Acabei de preparar um caso de teste (acredite, não sou bom em C / C ++, mas parecia 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;
}
Joseph Pecoraro
fonte
-5

Contanto que as strings possam ser vistas diretamente como um array de char, será muito difícil me convencer de que as strings são vistas como std::stringcidadãos de primeira classe em C ++.

Além disso, combinar alocação e limitação parece ser uma má ideia para mim de qualquer maneira.

Mat Noguchi
fonte
-7

Experimente esta macro. Em qualquer lugar que você quiser que o "verdadeiro" ou falso apareça, basta substituí-lo por PRINTBOOL (var) onde var é o bool para o qual você deseja o texto.

#define PRINTBOOL(x) x?"true":"false"
dagorym
fonte
2
Precisa de alguns parênteses nessa macro, provavelmente por isso você obteve o downvote.
postfuturist