Преобразование из std :: string в bool - PullRequest
45 голосов
/ 30 января 2010

Каков наилучший способ преобразования std :: string в bool? Я вызываю функцию, которая возвращает «0» или «1», и мне нужно чистое решение, чтобы превратить это в логическое значение.

Ответы [ 13 ]

80 голосов
/ 26 марта 2013

Я удивлен, что никто не упомянул это:

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

или

bool b;
istringstream("true") >> std::boolalpha >> b;
44 голосов
/ 30 января 2010
bool to_bool(std::string const& s) {
     return s != "0";
}
32 голосов
/ 30 января 2010

Вероятно, это будет излишним для вас, но я бы использовал boost :: lexical_cast

boost::lexical_cast<bool>("1") // returns true
boost::lexical_cast<bool>("0") // returns false
12 голосов
/ 30 января 2010

Либо вы беспокоитесь о возможности неверного возвращаемого значения, либо нет.Большинство ответов до сих пор находятся на среднем уровне, перехватывая некоторые строки помимо «0» и «1», возможно, рационализируя то, как их следует преобразовать, возможно, выбрасывая исключение. Неверный ввод не может привести к допустимому выводу, и вы не должны пытаться принять его.

Если вас не волнует неверный возврат, используйте s[0] == '1'.Это супер просто и очевидно.Если вы должны кому-то оправдать его допуск, скажите, что он преобразует неверный ввод в false, и в вашей реализации STL пустая строка, вероятно, будет одиночной \0, поэтому она достаточно стабильна.s == "1" тоже хорошо, но s != "0" кажется мне тупым и делает недействительным => true.

Если вы заботитесь об ошибках (и, вероятно, должны это сделать), используйте

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

Это ловит ВСЕ ошибки, это также очевидно и просто для всех, кто знает smidgen C, и ничего не будет работать быстрее.

6 голосов
/ 16 марта 2015

Существует также std :: stoi в c ++ 11:

bool value = std :: stoi (someString.c_str ());

2 голосов
/ 30 января 2010

Я бы использовал это, что делает то, что вы хотите, и ловит случай ошибки.

bool to_bool(const std::string& x) {
  assert(x == "0" || x == "1");
  return x == "1";
}
2 голосов
/ 30 января 2010

Написать бесплатную функцию:

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

Это самая простая вещь, которая может сработать, но вы должны спросить себя:

  • что должна возвращать пустая строка? версия выше выдает исключение
  • что должен преобразовать символ, отличный от '1' или '0'?
  • является ли строка из более чем одного символа допустимым вводом для функции?

Я уверен, что есть и другие - это радость дизайна API!

1 голос
/ 30 января 2010

Я бы изменил некрасивую функцию, которая возвращает эту строку в первую очередь.Для этого и нужен bool.

0 голосов
/ 15 апреля 2019

Ответ DavidL - лучший, но я хочу поддержать обе формы логического ввода одновременно.Таким образом, незначительное изменение темы (названное в честь 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;
}

Это поддерживает «0», «1», «true» и «false» в качестве допустимыхвходы.К сожалению, я не могу найти портативный способ также поддерживать "TRUE" и "FALSE"

0 голосов
/ 30 января 2010

Вы всегда можете обернуть возвращаемую строку в класс, который обрабатывает концепцию логических строк:

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

Позвоните примерно так:

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

Который будет выбрасывать invalid_argument, если нарушено правило о "0" и "1".

...