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
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
bool to_bool(std::string const& s) {
return s != "0";
}
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!
Questo è il metodo migliore, penso. Usare 'at' come il controllo è molto pulito. – GManNickG
@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. –
@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. –
Prova questo:
bool value;
if(string == "1")
value = true;
else if(string == "0")
value = false;
bool to_bool(std::string const &string) {
return string[0] == '1';
}
Cambierei la brutta funzione che restituisce questa stringa, in primo luogo. Ecco a cosa serve bool.
Non ho il controllo su questa funzione, è una libreria di terze parti. – cquillen
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
@UncleBens - forse usa std :: string come un tipo "variante". –
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());
}
Ma ma ... "DEADBEEF" sarebbe considerato falso! :-P –
E perché sarebbe vero? –
@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. –
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";
}
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.
Non tutto deve essere una classe; una funzione libera è molto più pulita e sicura. – GManNickG
@GMan, sarei il primo a dirlo :) –
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 .
Sono sorpreso che nessuno ha menzionato questo:
bool b;
istringstream("1") >> b;
o
bool b;
istringstream("true") >> std::boolalpha >> b;
La reputazione non sempre va con la risposta top (imho). :) – gsamaras
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
Sì, sono stream C++ https://www.cprogramming.com/tutorial/c++-iostreams.html. –
C'è anche std :: Stoi in C++ 11:
valore bool = std :: Stoi (someString.c_str());
Poiché questa soluzione include alcuni overhead, non dovresti usarla quando le prestazioni sono importanti. Oppure specializza boost :: lexical_cast per le tue esigenze. – smerlin
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
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