Conversione di bool in testo in C ++


93

Forse questa è una domanda stupida, ma esiste un modo per convertire un valore booleano in una stringa tale che 1 diventa "vero" e 0 diventa "falso"? Potrei semplicemente usare un'istruzione if, ma sarebbe bello sapere se c'è un modo per farlo con il linguaggio o le librerie standard. Inoltre, sono un pedante. :)


6
Obiezione! E la localizzazione? Perché una lingua stessa dovrebbe contenere costanti letterali specifiche della lingua?
valdo

1
@valdo - Sono abbastanza sicuro che per il progetto a cui stavo lavorando, l'internazionalizzazione non fosse un problema. A quel tempo, probabilmente era un progetto scolastico.
Jason Baker

Risposte:


118

Che ne dici di usare il linguaggio C ++ stesso?

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;

AGGIORNARE:

Se desideri più di 4 righe di codice senza alcun output della console, vai alla pagina cppreference.com che parla std::boolalphaestd::noboolalpha che mostra l'output della console e spiega di più sull'API .

Inoltre utilizzando std::boolalpha modificherà lo stato globale di std::cout, potresti voler ripristinare il comportamento originale.Vai qui per maggiori informazioni sul ripristino dello stato distd::cout .


Sono un principiante assoluto di C ++. Qualcuno può spiegarmi come funziona?
Chucky,

4
@Chucky Non sarai in grado di capire come funziona finché non capirai il sovraccarico dell'operatore . Spiegare come funziona andrebbe ben oltre lo scopo di questa domanda. Dovrai pubblicarlo come una domanda diversa o cercare le risposte esistenti a quella domanda. Raccomando quest'ultimo .
Michael Dorst

2
Questo stampa solo booleani come testo, non li converte in testo / stringa.
atoMerz

Allora in che modo questo non riesce il criterio "per convertire un valore booleano in una stringa" fornito dall'OP?
graham.reeds

2
Questo codice non converte un valore booleano in una stringa. Crea una variabile std::string stre salva il risultato della conversione in essa, se puoi.
rozina

76

Stiamo parlando di C ++, giusto? Perché diavolo stiamo ancora usando le macro !?

Le funzioni inline C ++ offrono la stessa velocità di una macro, con l'ulteriore vantaggio della sicurezza dei tipi e della valutazione dei parametri (che evita il problema menzionato da Rodney e dwj.

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

A parte questo, ho qualche altra lamentela, in particolare con la risposta accettata :)

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

Saluti :)


@DrPizza: Includere un'intera lib boost per una funzione così semplice? Stai scherzando?


@NathanFellman, la risposta accettata è troppo lenta. Questo può essere migliorato stringse le costanti stringa per "true" e "false" sono memorizzate in variabili const statiche.
Serge Rogatch

Questa è una risposta problematica, poiché: 1. A volte vuoi "sì" o "no" invece di "vero o" falso ", e talvolta" successo "vs" fallimento "ecc. 2. A volte vuoi lettere minuscole, a volte maiuscole caso, a volte caso del titolo.
einpoklum

2
Leggi la domanda, è esattamente ciò che è stato richiesto.
GU.

@einpoklum Niente ti impedisce di creare tutte le funzioni inline che desideri per le conversioni desiderate.
rozina

2
in uno scricchiolio puoi fare:cout << (bool_x ? "true": "false") << endl;
Trevor Boyd Smith

22

C ++ ha stringhe appropriate quindi potresti anche usarle. Sono nella stringa di intestazione standard. #include <stringa> per usarli. Niente più sovraccarichi di buffer strcat / strcpy; non più terminatori null mancanti; niente più disordinata gestione manuale della memoria; stringhe conteggiate corrette con semantica del valore appropriato.

C ++ ha anche la capacità di convertire i bool in rappresentazioni leggibili dall'uomo. Abbiamo visto suggerimenti in precedenza con gli esempi iostream, ma sono un po 'limitati perché possono solo mandare il testo alla console (o con fstreams, un file). Fortunatamente, i progettisti di C ++ non erano dei completi idioti; abbiamo anche iostream supportati non dalla console o da un file, ma da un buffer di stringhe gestito automaticamente. Si chiamano stringstream. #include <sstream> per ottenerli. Quindi possiamo dire:

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

Naturalmente, non vogliamo davvero scrivere tutto questo. Fortunatamente, C ++ ha anche una comoda libreria di terze parti chiamata Boost che può aiutarci qui. Boost ha una bella funzione chiamata lexical_cast. Possiamo usarlo così:

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

Ora, è vero che questo è un overhead più alto di alcune macro; stringstreams si occupa di localizzazioni che potrebbero non interessarti e creano una stringa dinamica (con allocazione di memoria) mentre la macro può produrre una stringa letterale, che lo evita. Ma il rovescio della medaglia, il metodo stringstream può essere utilizzato per moltissime conversioni tra rappresentazioni stampabili e interne. Puoi eseguirli all'indietro; boost :: lexical_cast <bool> ("true") fa la cosa giusta, per esempio. Puoi usarli con i numeri e in effetti qualsiasi tipo con gli operatori I / O formattati correttamente. Quindi sono abbastanza versatili e utili.

E se dopo tutto questo il tuo profiling e benchmarking rivela che lexical_casts sono un collo di bottiglia inaccettabile, è allora che dovresti considerare di fare un po 'di macro horror.


3
boost :: lexical_cast <bool> ("true") sembra lanciare un'eccezione bad_lexical_cast
Utente

3
non funziona nella mia app, "isExist:" + boost :: lexical_cast <std :: string> (isExit)); i risultati sonoEsiste: 0
Scott 混合 理论

7

Questo dovrebbe andare bene:


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

Ma, se vuoi farlo più 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

Se decidi di usare le macro (o stai usando C su un progetto futuro) dovresti aggiungere parentesi attorno alla 'b' nell'espansione della macro (non ho ancora abbastanza punti per modificare il contenuto di altre persone):

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

Questa è una tecnica di programmazione difensiva che protegge da errori nascosti dell'ordine di operazioni; cioè, come viene valutato per tutti i compilatori?

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

rispetto a

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

Anche prima di avere de 2k rep potresti effettivamente modificare i contenuti di altre persone. Sarà rivisto, ma ovviamente potresti.
SysDragon

2

Uso un ternario in un printf come questo:

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

Se lo macro:

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

quindi devi assicurarti che qualunque cosa tu passi in quanto 'b'non ha effetti collaterali. E non dimenticare le parentesi attorno a 'b'perché potresti ottenere errori di compilazione.


Dato che "b" compare solo una volta nella definizione macro, perché stai avvertendo degli effetti collaterali?
postfuturista

2

Con C ++ 11 potresti usare un lambda per ottenere un codice leggermente più compatto e un utilizzo sul posto:

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

Stampe:

string to print -> true


1

Senza trascinare ostream dentro:

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

0

Utilizzare boolalphaper stampare bool in stringa.

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

Riferimento C ++


0

Che ne dici del semplice:

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

-5

Sono d'accordo che una macro potrebbe essere la soluzione migliore. Ho appena preparato un test case (credimi, non sono bravo con C / C ++ ma sembrava divertente):

#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

Finché le stringhe possono essere visualizzate direttamente come un array di caratteri, sarà davvero difficile convincermi che std::stringrappresenta le stringhe come cittadini di prima classe in C ++.

Inoltre, combinare l'allocazione e il limite sembra comunque essere una cattiva idea.


-7

Prova questa macro. Ovunque tu voglia che "true" o false vengano visualizzate, sostituiscile con PRINTBOOL (var) dove var è il valore bool per cui vuoi il testo.

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

2
Hai bisogno di alcune parentesi in quella macro, che è probabilmente il motivo per cui hai ricevuto il voto negativo.
postfuturista
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.