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

这一生的挚爱 提交于 2020-02-26 10:15:30

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

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

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

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

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


#1楼

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


#2楼

可能的选项如下所述:

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.第四个选项: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进行更好的错误管理(参见此处 )。

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库。 所有其他解决方案都不鼓励或错误。


#3楼

在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需要指定基数。


#4楼

好吧,很多答案,很多可能性。 我在这里缺少的是一些将字符串转换为不同的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上,max int是2147483647.让我们为一个字符串赋值max int + 1:string str =“2147483648”。 现在,将字符串转换为int时:

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

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


#5楼

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

s是字符串, base是一个int例如2,8,10,16。)

有关strtol更多详细信息,请参阅此链接


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

由于strtol只处理char数组,我们需要将string转换为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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!