C++ 如何将 std::string 转换为 int?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7663709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:18:13  来源:igfitidea点击:

How can I convert a std::string to int?

c++stringint

提问by Brandon

Just have a quick question. I've looked around the internet quite a bit and I've found a few solutions but none of them have worked yet. Looking at converting a string to an int and I don't mean ASCII codes.

只是有一个快速的问题。我在互联网上看了很多,我找到了一些解决方案,但没有一个有效。考虑将字符串转换为 int,我不是指 ASCII 代码。

For a quick run-down, we are passed in an equation as a string. We are to break it down, format it correctly and solve the linear equations. Now, in saying that, I'm not able to convert a string to an int.

为了快速了解,我们以字符串形式传入一个等式。我们要把它分解,正确格式化并解出线性方程。现在,说到这里,我无法将字符串转换为 int。

I know that the string will be in either the format (-5) or (25) etc. so it's definitely an int. But how do we extract that from a string?

我知道字符串将采用 (-5) 或 (25) 等格式,所以它绝对是一个整数。但是我们如何从字符串中提取它呢?

One way I was thinking is running a for/while loop through the string, check for a digit, extract all the digits after that and then look to see if there was a leading '-', if there is, multiply the int by -1.

我想的一种方法是在字符串中运行 for/while 循环,检查一个数字,然后提取所有数字,然后查看是否有前导“-”,如果有,将 int 乘以 - 1.

It seems a bit over complicated for such a small problem though. Any ideas?

不过对于这样一个小问题来说似乎有点过于复杂了。有任何想法吗?

回答by tgmath

In C++11 there are some nice new convert functions from std::stringto a number type.

在 C++11 中,有一些不错的新的从std::string数字类型转换为数字类型的函数。

So instead of

所以代替

atoi( str.c_str() )

you can use

您可以使用

std::stoi( str )

where stris your number as std::string.

str你的号码在哪里std::string

There are version for all flavours of numbers: long stol(string), float stof(string), double stod(string),... see http://en.cppreference.com/w/cpp/string/basic_string/stol

有适用于所有数字的版本: long stol(string), float stof(string), double stod(string),... 参见http://en.cppreference.com/w/cpp/string/basic_string/stol

回答by Winston Ewert

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

To be fully correct you'll want to check the error flags.

为了完全正确,您需要检查错误标志。

回答by Claudio

The possible options are described below:

可能的选项如下所述:

1. First option: sscanf()

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

This is an error (also shown by cppcheck) because "scanf without field width limits can crash with huge input data on some versions of libc"(see here, and here).

这是一个错误(也由 cppcheck 显示),因为“在某些版本的 libc 上,没有字段宽度限制的 scanf 可能会因大量输入数据而崩溃”(请参阅此处此处)。

2. Second option: std::sto*()

2. 第二种选择:std::sto*()

    #include <iostream>
    #include <string>

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

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

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

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

This solution is short and elegant, but it is available only on on C++11 compliant compilers.

此解决方案简短而优雅,但仅适用于符合 C++11 的编译器。

3. Third option: sstreams

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 ??

However, with this solution is hard to distinguish between bad input (see here).

但是,使用此解决方案很难区分错误输入(请参阅此处)。

4. Fourth option: Boost's lexical_cast

4. 第四个选项:Boost 的 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
        }

However, this is just a wrapper of sstream, and the documentation suggests to use sstreamfor better error management (see here).

但是,这只是 的包装器sstream,文档建议sstream用于更好的错误管理(请参阅此处)。

5. Fifth option: strto*()

5. 第五个选项:strto*()

This solution is very long, due to error management, and it is described here. Since no function returns a plain int, a conversion is needed in case of integer (see herefor how this conversion can be achieved).

由于错误管理,此解决方案很长,在此处进行描述。由于没有函数返回普通的 int,因此在整数的情况下需要进行转换(有关如何实现此转换,请参见此处)。

6. Sixth option: Qt

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     

Conclusions

结论

Summing up, the best solution is C++11 std::stoi()or, as a second option, the use of Qt libraries. All other solutions are discouraged or buggy.

总而言之,最好的解决方案是 C++11,std::stoi()或者作为第二个选择,使用 Qt 库。所有其他解决方案都是不鼓励或有问题的。

回答by brenjt

use the atoi function to convert the string to an integer:

使用 atoi 函数将字符串转换为整数:

string a = "25";

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

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

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

回答by Rob?

What about Boost.Lexical_cast?

Boost.Lexical_cast怎么样?

Here is their example:

这是他们的例子:

The following example treats command line arguments as a sequence of numeric data:

以下示例将命令行参数视为数字数据序列:

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);
        }
    }
    ...
}

回答by Nawaz

Admittedly, my solution wouldn't work for negative integers, but it will extract all positive integers from input text containing integers. It makes use of numeric_onlylocale:

诚然,我的解决方案不适用于负整数,但它会从包含整数的输入文本中提取所有正整数。它使用numeric_only语言环境:

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

Input text:

输入文本:

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

Output integers:

输出整数:

 5
25
7987
78
9878

The class numeric_onlyis defined as:

该类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];
    }
};

Complete online demo : http://ideone.com/dRWSj

完整的在线演示:http: //ideone.com/dRWSj

回答by James Kanze

It's probably a bit of overkill, but boost::lexical_cast<int>( theString )should to the job quite well.

这可能有点矫枉过正,但 boost::lexical_cast<int>( theString )应该很好地完成工作。

回答by Eric

atoiis a built-in function that converts a string to an integer, assuming that the string begins with an integer representation.

atoi是一个将字符串转换为整数的内置函数,假设字符串以整数表示形式开始。

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

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

回答by Jichao

In Windows, you could use:

在 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,stringstreamneed to specify the base if you need to interpret hexdecimal.

strtol,stringstream如果需要解释十六进制,需要指定基数。

回答by Andrushenko Alexander

Well, lot of answers, lot of possibilities. What I am missing here is some universal method that converts a string to different C++ integral types (short, int, long, bool, ...). I came up with following solution:

嗯,很多答案,很多可能性。我在这里缺少的是一些将字符串转换为不同 C++ 整数类型(short、int、long、bool 等)的通用方法。我想出了以下解决方案:

#include<sstream>
#include<exception>
#include<string>
#include<type_traits>

using namespace std;

template<typename T>
T toIntegralType(const string &str) {
    static_assert(is_integral<T>::value, "Integral type required.");
    T ret;
    stringstream ss(str);
    ss >> ret;
    if ( to_string(ret) != str)
        throw invalid_argument("Can't convert " + str);
    return ret;
}

Here are examples of usage:

以下是使用示例:

string str = "123";
int x = toIntegralType<int>(str); // x = 123

str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int

str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception

Why not just use stringstream output operator to convert a string into an integral type? Here is the answer: Let's say a string contains a value that exceeds the limit for intended integral type. For examle, on Wndows 64 max int is 2147483647. Let's assign to a string a value max int + 1: string str = "2147483648". Now, when converting the string to an int:

为什么不直接使用 stringstream 输出运算符将字符串转换为整数类型?答案如下:假设一个字符串包含一个超出预期整数类型限制的值。例如,在 Wndows 64 上,max int 是 2147483647。让我们为字符串分配一个值 max int + 1:string str = "2147483648"。现在,将字符串转换为 int 时:

stringstream ss(str);
int x;
ss >> x;

x becomes 2147483647, what is definitely an error: string "2147483648" was not supposed to be converted to the int 2147483647. The provided function toIntegralType spots such errors and throws exception.

x 变为 2147483647,这绝对是一个错误:字符串“2147483648”不应该被转换为 int 2147483647。提供的函数 toIntegralType 会发现此类错误并抛出异常。