2010-01-29 1 views
38

Qual è il modo migliore per convertire una stringa: std :: bool? Sto chiamando una funzione che restituisce "0" o "1", e ho bisogno di una soluzione pulita per trasformarlo in un valore booleano.Conversione da std :: string a bool

risposta

29

Sarà probabilmente eccessivo per voi, ma io userei boost::lexical_cast

boost::lexical_cast<bool>("1") // returns true 
boost::lexical_cast<bool>("0") // returns false 
+0

Poiché questa soluzione include alcuni overhead, non dovresti usarla quando le prestazioni sono importanti. Oppure specializza boost :: lexical_cast per le tue esigenze. – smerlin

+0

Se puoi permetterti di convertire stringhe in bool ... Ad ogni modo, +1: questo è il metodo più efficace finora. E se risulta troppo lento, non sarebbe possibile specializzare lexical_cast /beg the boost people to do it? :) – UncleBens

+2

Com'è più robusto di qualsiasi altra cosa? Il suo comportamento non è chiaro, ad esempio, i numeri non nulli casuali diventano veri, "true" e la stringa vuota deve generare eccezioni. (Non sicuro a priori.) – Potatoswatter

37
bool to_bool(std::string const& s) { 
    return s != "0"; 
} 
2

Scrivi una funzione libera:

bool ToBool(const std::string & s) { 
    return s.at(0) == '1'; 
} 

Questo è circa la cosa più semplice che potrebbe funzionare, ma è necessario chiedersi:

  • cosa dovrebbe fare un ritorno stringa vuota? la versione precedente genera un'eccezione
  • come convertire un carattere diverso da "1" o "0"?
  • è una stringa di più di un carattere un input valido per la funzione?

Sono sicuro che ce ne sono altri - questa è la gioia del design dell'API!

+0

Questo è il metodo migliore, penso. Usare 'at' come il controllo è molto pulito. – GManNickG

+4

@GMan: Non sono sicuro di essere d'accordo. In C, 0 è falso, e tutto il resto è vero. Quindi, 2 è vero, 03 è vero, ecc. Quindi, anche se la domanda è poco specificata, è ragionevole presumere che tutto ciò che non è zero è vero. –

+0

@Chris Che ne dici di "00"? Il mio punto in questa risposta è che anche per una funzione così semplice, ci sono molti problemi che devono essere esplorati. –

0

Prova questo:

bool value; 

if(string == "1") 
    value = true; 
else if(string == "0") 
    value = false; 
+2

Sfortunatamente questo lascia un valore in uno stato indeterminato se la stringa deve contenere qualcos'altro. – UncleBens

+3

@UncleBens: più probabilmente, il suo valore sarebbe FileNotFound. :-P –

+1

Chris: I rofl'd. – GManNickG

0
bool to_bool(std::string const &string) { 
    return string[0] == '1'; 
} 
1

Cambierei la brutta funzione che restituisce questa stringa, in primo luogo. Ecco a cosa serve bool.

+0

Non ho il controllo su questa funzione, è una libreria di terze parti. – cquillen

+0

La biblioteca sembra un po 'stupida, però. C'è qualche ragione per cui dovrebbe usare 'std :: string' di tutte le cose per un ritorno booleano? – UncleBens

+0

@UncleBens - forse usa std :: string come un tipo "variante". –

0

Ecco un modo simile a Kyle tranne che gestisce gli zeri iniziali e roba:

bool to_bool(std::string const& s) { 
    return atoi(s.c_str()); 
} 
+3

Ma ma ... "DEADBEEF" sarebbe considerato falso! :-P –

+0

E perché sarebbe vero? –

+0

@Andreas: la tradizione C è che 0 è falso e tutto il resto è vero. Idealmente mi piacerebbe lanciare un'eccezione in quel caso, ma se questa non è un'opzione, a mio avviso il vero è "meno sbagliato" che falso. –

2

I' d usa questo, che fa quello che vuoi, e cattura il caso di errore.

bool to_bool(const std::string& x) { 
    assert(x == "0" || x == "1"); 
    return x == "1"; 
} 
0

Si può sempre avvolgere la stringa restituita in una classe che gestisce il concetto di stringhe booleane:

class BoolString : public string 
{ 
public: 
    BoolString(string const &s) 
    : string(s) 
    { 
     if (s != "0" && s != "1") 
     { 
      throw invalid_argument(s); 
     } 
    } 

    operator bool() 
    { 
     return *this == "1"; 
    } 
} 

chiamata qualcosa di simile:

BoolString bs(func_that_returns_string()); 
if (bs) ...; 
else ...; 

Quale getterà invalid_argument se il regola su "0" e "1" viene violato.

+1

Non tutto deve essere una classe; una funzione libera è molto più pulita e sicura. – GManNickG

+0

@GMan, sarei il primo a dirlo :) –

9

O ti interessa la possibilità di un valore di ritorno non valido o non lo fai. La maggior parte delle risposte finora sono in mezzo, catturando alcune stringhe oltre a "0" e "1", forse razionalizzando il modo in cui dovrebbero essere convertite, forse lanciando un'eccezione. L'input non valido non può produrre un output valido e non si deve provare ad accettarlo.

Se non si cura dei resi non validi, utilizzare s[0] == '1'. È super semplice e ovvio. Se devi giustificare la sua tolleranza a qualcuno, dì che converte l'input non valido in falso, e la stringa vuota è probabilmente un singolo \0 nell'implementazione STL, quindi è ragionevolmente stabile. s == "1" è anche buono, ma s != "0" sembra ottuso per me e rende non valido => true.

Se non si preoccupano gli errori (e probabilmente dovrebbe), utilizzare

if (s.size() != 1 
|| s[0] < '0' || s[0] > '1') throw input_exception(); 
b = (s[0] == '1'); 

Questa cattura tutti gli errori, è anche senza mezzi termini ovvio e semplice a chiunque conosca un pizzico di C, e nulla si esibiranno più velocemente .

61

Sono sorpreso che nessuno ha menzionato questo:

bool b; 
istringstream("1") >> b; 

o

bool b; 
istringstream("true") >> std::boolalpha >> b; 
+2

La reputazione non sempre va con la risposta top (imho). :) – gsamaras

+0

Bello! Questo ha funzionato per me utilizzando l'API Lua C.Immagino che C non abbia un tipo di dati booleano ; lua_toboolean() restituisce un valore int di 0 o 1, quindi questo sembra fare il trucco in C++. – Artorias2718

+0

Sì, sono stream C++ https://www.cprogramming.com/tutorial/c++-iostreams.html. –

5

C'è anche std :: Stoi in C++ 11:

valore bool = std :: Stoi (someString.c_str());