Как преобразовать std:: string в int?

только вопросик. Я немного посмотрел в интернете, и я нашел несколько решений, но ни одно из них еще не сработало. Глядя на преобразование строки в int, я не имею в виду коды ASCII.

для быстрого разбега мы передаем уравнение в виде строки. Мы должны разбить его, правильно отформатировать и решить линейные уравнения. Теперь, говоря это, я не могу преобразовать строку в int.

Я знаю, что строка будет в либо формат (-5), либо (25) и т. д. так что это определенно int. Но как извлечь это из строки?

один из способов, о котором я думал, - это запустить цикл for/while через строку, проверить цифру, извлечь все цифры после этого, а затем посмотреть, есть ли ведущий' -', если есть, умножьте int на -1.

Это кажется немного более сложным для такой маленькой проблемой, хотя. Есть идеи?

11 ответов


в C++11 есть некоторые хорошие новые функции преобразования из std::string к типу число.

так вместо

atoi( str.c_str() )

можно использовать

std::stoi( str )

здесь str - Это ваш номер как std::string.

есть версия для всех вкусов чисел: long stol(string), float stof(string), double stod(string),... см.http://en.cppreference.com/w/cpp/string/basic_string/stol


std::istringstream ss(thestring);
ss >> thevalue;

чтобы быть полностью корректным, вы захотите проверить флаги ошибок.


используйте функцию atoi для преобразования строки в целое число:

string a = "25";

int b = atoi(a.c_str());

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/


возможные варианты описаны ниже:

1. Первый вариант: sscanf ()

    #include <cstdio>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        if(sscanf(str.c_str(), "%d", &i) != 1)
            // error management

        // string -> float
        if(sscanf(str.c_str(), "%f", &f) != 1)
            // error management

        // string -> double 
        if(sscanf(str.c_str(), "%lf", &d) != 1)
            // error management

Это ошибка (также показанная cppcheck), потому что "scanf без ограничений ширины поля может разбиться с огромными входными данными на некоторых версиях libc" (см. здесь и здесь).

2. Второй вариант: std:: sto*()

    #include <iostream>
    #include <string>

        int i;
        float f;
        double d;
        std::string str;

        try {
            // string -> integer
            int i = std::stoi(s);

            // string -> float
            float f = std::stof(s);

            // string -> double 
            double d = std::stod(s);
        } catch (...) {
            // error management
        }   

это решение короткое и элегантное, но это доступно только на компиляторах C++11 compliants.

3. Третий вариант: sstreams

    #include <string>
    #include <sstream>

        int i;
        float f;
        double d;
        std::string str;

        // string -> integer
        std::istringstream ( str ) >> i;

        // string -> float
        std::istringstream ( str ) >> f;

        // string -> double 
        std::istringstream ( str ) >> d;

        // error management ??

однако с этим решением трудно отличить плохой ввод (см. здесь).

4. Четвертый вариант: увеличить по lexical_cast

    #include <boost/lexical_cast.hpp>
    #include <string>

        std::string str;

        try {
            int i = boost::lexical_cast<int>( str.c_str());
            float f = boost::lexical_cast<int>( str.c_str());
            double d = boost::lexical_cast<int>( str.c_str());
            } catch( boost::bad_lexical_cast const& ) {
                // Error management
        }

однако это всего лишь оболочка sstream, и документация предлагает использовать sstrem для лучшего управления ошибками (см. здесь).

5. Пятый вариант: strto*()

это решение очень длинное, из-за управления ошибками, и оно описано здесь. Поскольку никакая функция не возвращает простой int, преобразование необходимо в случае integer (см. здесь как это преобразование может быть достигнуто).

6. Шестой вариант: Qt

    #include <QString>
    #include <string>

        bool ok;
        std::string;

        int i = QString::fromStdString(str).toInt(&ok);
        if (!ok)
            // Error management

        float f = QString::fromStdString(str).toFloat(&ok);
        if (!ok)
            // Error management 

        double d = QString::fromStdString(str).toDouble(&ok);
        if (!ok)
    // Error management     

выводы

Подводя итог, лучшим решением является C++11 std:: stoi() или, как второй вариант, использование библиотек Qt. Все остальные решения обескуражены или ошибочны.


насчет импульс.Lexical_cast?

вот пример:

в следующем примере аргументы командной строки рассматриваются как последовательность числовых данных:

int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}

по общему признанию, мое решение не будет работать для отрицательных целых чисел, но оно извлечет все положительные целые из входного текста, содержащего целые числа. Он использует numeric_only locale:

int main() {
        int num;
        std::cin.imbue(std::locale(std::locale(), new numeric_only()));
        while ( std::cin >> num)
             std::cout << num << std::endl;
        return 0;
}

ввод текста:

 the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878

вывод чисел:

 5
25
7987
78
9878

класс numeric_only определено как:

struct numeric_only: std::ctype<char> 
{
    numeric_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
        return &rc[0];
    }
};

полная онлайн-демонстрация:http://ideone.com/dRWSj


Это, вероятно, немного перебор, но boost::lexical_cast<int>( theString ) должен к работе весьма неплохо.


atoi-это встроенная функция, которая преобразует строку в целое число, при условии, что строка начинается с представления целого числа.

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/


В Windows, вы можете использовать:

const std::wstring hex = L"0x13";
const std::wstring dec = L"19";

int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
    std::cout << ret << "\n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
    std::cout << ret << "\n";
}

strtol,stringstream нужно указать базу, если вам нужно интерпретировать hexdecimal.


это обычно работает, когда я использую его:

int myint = int::Parse(mystring);

есть еще один простой способ : предположим, у вас есть персонаж, как c='4' поэтому вы можете сделать один из следующих шагов:

1st: int q

q=(int) c ; (q is now 52 in ascii table ) . q=q-48; remember that adding 48 to digits is their ascii code .

второй способ :

q=c-'0'; the same , character '0' means 48