关于c ++:如何将std :: string转换为int?

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

快问一个问题。我环顾了一下互联网,找到了一些解决方案,但都没有奏效。看看把一个字符串转换成一个int,我的意思不是ASCII码。

为了进行快速的向下搜索,我们以字符串的形式传递一个方程。我们要把它分解,正确格式化,解线性方程组。现在,这么说,我无法将字符串转换为int。

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

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

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


在C++ 11中,有一些不错的新的转换函数,从EDCOX1,4,到数字类型。

因此,而不是

1
atoi( str.c_str() )

你可以使用

1
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


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

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


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

1
2
3
string a ="25";

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

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


可能的选项如下所述:

1。第一个选项:SScanf()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    #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*()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    #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兼容编译器上使用。

三。第三种选择:S流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    #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。第四种选择:Boost的词法转换

1
2
3
4
5
6
7
8
9
10
11
12
    #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,所以在使用整数的情况下需要进行转换(有关如何实现此转换的信息,请参阅此处)。

6。第六个选项:qt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    #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::StIO(),或者作为第二个选项,使用Qt库。所有其他的解决方案都是不鼓励的或有缺陷的。


Boost.Lexical_Cast怎么样?

以下是他们的例子:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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语言环境:

1
2
3
4
5
6
7
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;
}

输入文本:

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

输出整数:

1
2
3
4
5
 5
25
7987
78
9878

numeric_only类定义为:

1
2
3
4
5
6
7
8
9
10
11
12
13
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( theString )应该去工作相当好。


我的代码:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;

int main()
{
    string s="32";  //String
    int n=stoi(s);  //Convert to int
    cout << n + 1 << endl;

    return 0;
}

从http://///stoi www.cplusplus.com字符串参考号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// stoi example
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoi

int main ()
{
  std::string str_dec ="2001, A Space Odyssey";
  std::string str_hex ="40c3";
  std::string str_bin ="-10010110001";
  std::string str_auto ="0x7f";

  std::string::size_type sz;   // alias of size_t

  int i_dec = std::stoi (str_dec,&sz);
  int i_hex = std::stoi (str_hex,nullptr,16);
  int i_bin = std::stoi (str_bin,nullptr,2);
  int i_auto = std::stoi (str_auto,nullptr,0);

  std::cout << str_dec <<":" << i_dec <<" and [" << str_dec.substr(sz) <<"]
"
;
  std::cout << str_hex <<":" << i_hex << '
'
;
  std::cout << str_bin <<":" << i_bin << '
'
;
  std::cout << str_auto <<":" << i_auto << '
'
;

  return 0;
}

输出:

2001年,太空奥德赛:2001太空奥德赛]和[,

40c3:16579

- 10010110001:1201

0x7F):127


嗯,很多答案,很多可能性。我这里缺少的是一些将字符串转换成不同C++整数类型(String,int,Load,Boo..…)的通用方法。我提出了以下解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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;
}

以下是用法示例:

1
2
3
4
5
6
7
8
9
10
11
12
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

为什么不使用Stringstream输出运算符将字符串转换为整型?答案如下:假设字符串包含的值超过了预期整型的限制。例如,在wndows 64上,max int为2147483647。让我们为字符串指定一个值max int+1:string str="2147483648"。现在,将字符串转换为int时:

1
2
3
stringstream ss(str);
int x;
ss >> x;

x变为2147483647,这绝对是一个错误:字符串"2147483648"不应该转换为int 2147483647。提供给integraltype的函数发现此类错误并引发异常。


在Windows中,您可以使用:

1
2
3
4
5
6
7
8
9
10
11
12
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 <<"
"
;
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
    std::cout << ret <<"
"
;
}

strtolstringstream需要指定基数才能解释十六进制。


atoi是一个内置函数,它将字符串转换为整数,前提是字符串以整数表示形式开头。

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


一个在线版:long n = strtol(s.c_str(), NULL, base);

(s是字符串,和一个baseint如2,8,10,16)。

你可以到这个链接,指的是strtol更多细节。

的核心思想是使用strtol函数,这是包含在cstdlib

由于strtol只处理与char数组,我们需要转换到charstring阵列。你可以参考这一环节。

一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>   // string type
#include <bitset>   // bitset type used in the output

int main(){
    s ="1111000001011010";
    long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string

    cout << s << endl;
    cout << t << endl;
    cout << hex << t << endl;
    cout << bitset<16> (t) << endl;

    return 0;
}

这将输出:

1
2
3
4
1111000001011010
61530
f05a
1111000001011010

还有一个简单的方法:假设您有一个像c='4'这样的字符,那么您可以执行以下步骤之一:

第一:INQ

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


这通常在我使用它时起作用:

1
int myint = int::Parse(mystring);