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

时间:2011-10-05 15:23:45

标签: c++ string int

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

对于快速破败,我们将方程作为字符串传递。我们要将其分解,正确格式化并求解线性方程。现在,在说,我无法将字符串转换为int。

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

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

虽然这个小问题看起来有点过于复杂。有什么想法吗?

22 个答案:

答案 0 :(得分:607)

在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

答案 1 :(得分:57)

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

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

答案 2 :(得分:36)

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

string a = "25";

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

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

答案 3 :(得分:32)

可能的选项如下所述:

<强> 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显示),因为没有字段宽度限制的&#34; scanf会因某些版本的libc&#34; 上的大量输入数据而崩溃(请参阅{{3} }和here)。

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

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

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

但是,这只是sstream的包装,文档建议使用sstrem进行更好的错误管理(参见here)。

<强> 5。第五种选择:strto *()

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

<强> 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库。 所有其他解决方案都是气馁或错误的。

答案 4 :(得分:9)

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

答案 5 :(得分:5)

不可否认,我的解决方案不适用于负整数,但它会从包含整数的输入文本中提取所有正整数。它使用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;
}

输入文字:

 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

答案 6 :(得分:4)

这可能有点矫枉过正,但是 boost::lexical_cast<int>( theString )应该胜任这项工作 很好。

答案 7 :(得分:1)

嗯,很多答案,很多可能性。我在这里缺少的是将字符串转换为不同的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;
}

以下是用法示例:

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最大int是2147483647。 让我们为字符串赋值max int + 1:字符串str =“ 2147483648”。 现在,将字符串转换为int时:

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

x变成2147483647,这绝对是一个错误:不应将字符串“ 2147483648”转换为int2147483647。提供给integralType的函数会发现此类错误并引发异常。

答案 8 :(得分:1)

我知道这个问题确实很老,但是我认为有一个更好的方法

#include <string>
#include <sstream>

bool string_to_int(std::string value, int * result) {
  std::stringstream stream1, stream2;
  std::string stringednumber;
  int tempnumber;
  stream1 << value;
  stream1 >> tempnumber;
  stream2 << tempnumber;
  stream2 >> stringednumber;
  if (!value.compare(stringednumber)) {
    *result = tempnumber;
    return true;
  }
  else return false;
}

如果我正确地编写了代码,它将返回一个布尔值,该值告诉您字符串是否为有效数字,如果为false,则不是数字,如果为true,则为数字,并且现在是该数字,您可以这样称呼:

std::string input;
std::cin >> input;
bool worked = string_to_int(input, &result);

答案 9 :(得分:1)

1。 std :: stoi

std::string str = "10";  
int number = std::stoi(str); 

2。字符串流

std::string str = "10";  
int number;  
std::istringstream(str) >> number

3。 boost :: lexical_cast

#include <boost/lexical_cast.hpp>
std::string str = "10";  
int number;
    
try 
{
    number = boost::lexical_cast<int>(str);
    std::cout << number << std::endl;
}
catch (boost::bad_lexical_cast const &e) // bad input
{
    std::cout << "error" << std::endl;
}

4。 std :: atoi

std::string str = "10";
int number = std::atoi(str.c_str()); 

5。 sscanf()

 std::string str = "10";
 int number;
 if (sscanf(str .c_str(), "%d", &number) == 1) 
 {
     std::cout << number << '\n';
 } 
 else 
 {
     std::cout << "Bad Input";
 }

答案 10 :(得分:1)

我的代码:

#include <iostream>
using namespace std;

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

    return 0;
}

答案 11 :(得分:1)

来自http://www.cplusplus.com/reference/string/stoi/

// 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) << "]\n";
  std::cout << str_hex << ": " << i_hex << '\n';
  std::cout << str_bin << ": " << i_bin << '\n';
  std::cout << str_auto << ": " << i_auto << '\n';

  return 0;
}

输出:

2001,太空漫游:2001年和[,太空漫游]

40c3:16579

-10010110001:-1201

0x7f:127

答案 12 :(得分:1)

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

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

答案 13 :(得分:1)

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

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

答案 14 :(得分:0)

单行版本:long n = strtol(s.c_str(), NULL, base);

({s是字符串,baseint,例如2、8、10、16。)

有关strtol的更多详细信息,请参考this link


核心思想是使用cstdlib中包含的strtol函数。

由于strtol仅处理char数组,因此我们需要将string转换为char数组。您可以参考this link

一个例子:

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

它将输出:

1111000001011010
61530
f05a
1111000001011010

答案 15 :(得分:0)

ll toll(string a){
    ll ret=0;
    bool minus=false;
    for(auto i:a){
        if(i=='-'){ minus=true; continue; }
        ret*=10;
        ret+=(i-'0');
    } if(minus) ret*=-1;
    return ret;
    # ll is defined as, #define ll long long int
    # usage: ll a = toll(string("-1234"));
}

答案 16 :(得分:0)

要从字符串表示形式转换为整数值,可以使用std :: stringstream。

如果转换的值超出整数数据类型的范围,则返回INT_MIN或INT_MAX。

如果字符串值不能表示为有效的int数据类型,则返回0。

#include 
#include 
#include 

int main() {

    std::string x = "50";
    int y;
    std::istringstream(x) >> y;
    std::cout << y << '\n';
    return 0;
}

输出: 50

根据上面的输出,我们可以看到它已从字符串数字转换为整数。

string to int c++上的来源及更多信息

答案 17 :(得分:0)

为了更加详尽(并按照注释中的要求),我添加了C ++ 17使用std::from_chars给出的解决方案。

std::string str = "10";
int number;
std::from_chars(str.data(), str.data()+str.size(), result);

如果要检查转换是否成功:

std::string str = "10";
int number;
auto [ptr, ec] = std::from_chars(str.data(), str.data()+str.size(), result);
assert(ec == std::errc{});
// ptr points to chars after read number

此外,要比较所有这些解决方案的性能,请参见以下快速指南链接:https://quick-bench.com/q/GBzK53Gc-YSWpEA9XskSZLU963Y

({std::from_chars是最快的,而std::istringstream是最慢的)

答案 18 :(得分:0)

 int stringToInt(std::string value) {    
 if(value.length() == 0 ) return 0; //tu zmiana..

 if (value.find(  std::string("NULL") ) != std::string::npos) {
     return 0;
  }
 
  if (value.find(  std::string("null") ) != std::string::npos) {
     return 0;
  }
 
 
int i;
std::stringstream stream1;
stream1.clear();
stream1.str(value);
stream1 >> i;
return i;

};

答案 19 :(得分:-2)

还有另一种简单的方法:假设您有一个像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

答案 20 :(得分:-2)

如果您使用硬编码 :)

bool strCanBeInt(std::string string){
    for (char n : string) {
        if (n != '0' && n != '1' && n != '2' && n != '3' && n != '4' && n != '5'
            && n != '6' && n != '7' && n != '8' && n != '9') {
            return false;
        }
    }
    return true;
}

int strToInt(std::string string) {
    int integer = 0;
    int numInt;
    for (char n : string) {
        if(n == '0') numInt = 0;
        if(n == '1') numInt = 1;
        if(n == '2') numInt = 2;
        if(n == '3') numInt = 3;
        if(n == '4') numInt = 4;
        if(n == '5') numInt = 5;
        if(n == '6') numInt = 6;
        if(n == '7') numInt = 7;
        if(n == '8') numInt = 8;
        if(n == '9') numInt = 9;
        if (integer){
            integer *= 10;
        }
        integer += numInt;
    }
    return integer;
}

答案 21 :(得分:-3)

这通常适用于我使用它:

int myint = int::Parse(mystring);