web-dev-qa-db-fra.com

Conversion d'une chaîne std :: en bool

Quelle est la meilleure façon de convertir une chaîne std :: en bool? J'appelle une fonction qui retourne "0" ou "1", et j'ai besoin d'une solution propre pour la transformer en valeur booléenne.

46
cquillen

Ce sera probablement exagéré pour vous, mais j'utiliserais boost :: lexical_cast

boost::lexical_cast<bool>("1") // returns true
boost::lexical_cast<bool>("0") // returns false
32
Kornel Kisielewicz

Je suis surpris que personne n'ait mentionné celui-ci:

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

ou

bool b;
istringstream("true") >> std::boolalpha >> b;
83
David L.
bool to_bool(std::string const& s) {
     return s != "0";
}
45
Chris Jester-Young

Soit vous vous souciez de la possibilité d'une valeur de retour non valide, soit vous ne le faites pas. Jusqu'à présent, la plupart des réponses se situent entre les deux, capturant certaines chaînes en plus de "0" et "1", rationalisant peut-être la façon dont elles devraient être converties, levant peut-être une exception. ne entrée non valide ne peut pas produire une sortie valide, et vous ne devriez pas essayer de l'accepter.

Si vous ne vous souciez pas des retours non valides, utilisez s[0] == '1'. C'est super simple et évident. Si vous devez justifier sa tolérance à quelqu'un, dites qu'il convertit une entrée non valide en false, et la chaîne vide est susceptible d'être un simple \0 dans votre implémentation STL, il est donc relativement stable. s == "1" est également bon, mais s != "0" me semble obtus et rend invalide => vrai.

Si vous vous souciez des erreurs (et devriez probablement le faire), utilisez

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

Cela attrape TOUTES les erreurs, c'est aussi carrément évident et simple pour quiconque connaît un smidgen de C, et rien ne fonctionnera plus rapidement.

12
Potatoswatter

Il y a aussi std :: stoi en c ++ 11:

valeur booléenne = std :: stoi (someString.c_str ());

6
Mike

J'utiliserais cela, qui fait ce que vous voulez, et attrape le cas d'erreur.

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

Écrivez une fonction gratuite:

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

Il s'agit de la chose la plus simple qui pourrait fonctionner, mais vous devez vous demander:

  • que doit renvoyer une chaîne vide? la version ci-dessus lève une exception
  • en quoi un caractère autre que "1" ou "0" doit-il être converti?
  • une chaîne de plusieurs caractères est-elle une entrée valide pour la fonction?

Je suis sûr qu'il y en a d'autres - c'est la joie de la conception d'API!

2
anon

Je changerais la fonction laide qui renvoie cette chaîne en premier lieu. C'est à ça que sert le bool.

1
rmn

réponse de DavidL est le meilleur, mais je me retrouve à vouloir prendre en charge les deux formes d'entrée booléenne en même temps. Donc, une variation mineure sur le thème (nommé d'après std::stoi ):

bool stob(std::string s, bool throw_on_error = true)
{
    auto result = false;    // failure to assert is false

    std::istringstream is(s);
    // first try simple integer conversion
    is >> result;

    if (is.fail())
    {
        // simple integer failed; try boolean
        is.clear();
        is >> std::boolalpha >> result;
    }

    if (is.fail() && throw_on_error)
    {
        throw std::invalid_argument(s.append(" is not convertable to bool"));
    }

    return result;
}

Cela prend en charge "0", "1", "true" et "false" comme entrées valides. Malheureusement, je ne peux pas trouver un moyen portable de prendre également en charge "TRUE" et "FALSE"

1
jwm

Voici un moyen similaire à celui de Kyle, sauf qu'il gère les principaux zéros et autres choses:

bool to_bool(std::string const& s) {
     return atoi(s.c_str());
}
0
Mahmoud Al-Qudsi

Essaye ça:

bool value;

if(string == "1")
    value = true;
else if(string == "0")
    value = false;
0
Kyle Lutz
bool to_bool(std::string const &string) { 
    return string[0] == '1';
}
0
Jerry Coffin

Vous pouvez toujours envelopper la chaîne retournée dans une classe qui gère le concept de chaînes booléennes:

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

Appelez quelque chose comme ceci:

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

Ce qui jettera invalid_argument si la règle concernant "0" et "1" est violé.

0
Matt Joiner