我想将一个字符串转换为int,我不是指ASCII码。

为了快速回顾,我们将一个方程作为字符串传递。我们要把它分解,正确地格式化并解出线性方程。说到这里,我不能把一个字符串转换成int型。

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

我想到的一种方法是在字符串中运行一个for/while循环,检查一个数字,提取后面的所有数字,然后看看是否有前导'-',如果有,将int乘以-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";
 }

其他回答

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

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

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

第一个:int q

Q =(int) c;(q现在在ASCII表中是52)。 q = q-48;记住,数字加48是他们的ASCII码。

第二种方式:

q = c - ' 0 ';同样,字符“0”表示48

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

(s为字符串,base为int,如2,8,10,16)

你可以参考这个链接了解更多关于strtol的细节。


核心思想是使用sttol函数,该函数包含在cstdlib中。

由于strtol只处理char数组,我们需要将字符串转换为char数组。你可以参考这个链接。

一个例子:

#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

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

可能的选择如下:

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也显示了),因为“在libc的某些版本上,没有字段宽度限制的scanf会因大量输入数据而崩溃”(参见这里和这里)。

2. std::我()*

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

这个解决方案短小精悍,但只能在c++ 11兼容的编译器上使用。

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的包装器,文档建议使用sstream来更好地管理错误(请参阅这里)。

5. strto () *

由于错误管理,这个解决方案很长,这里将对其进行描述。由于没有函数返回纯int,因此需要对整数进行转换(参见这里了解如何实现这种转换)。

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库。所有其他的解决方案都是不鼓励的或有缺陷的。