首页 文章

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

提问于
浏览
351

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

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

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

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

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

12 回答

  • 32

    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

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

  • 24

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

  • 9

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

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

  • -2
    std::istringstream ss(thestring);
    ss >> thevalue;
    

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

  • 54

    这通常适用于我使用它:

    int myint = int::Parse(mystring);
    
  • -2

    可能的选项如下所述:

    1. First option: 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 without field width limits can crash with huge input data on some versions of libc"(参见herehere) .

    2. Second option: 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兼容编译器 .

    3. Third option: 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. Fourth option: Boost's 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. Fifth option: strto()*

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

    6. Sixth option: 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

    总之,最好的解决方案是C 11 std :: stoi(),或作为第二种选择,使用Qt库 . 所有其他解决方案都是气馁或缺陷 .

  • 5

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

    string a = "25";
    
    int b = atoi(a.c_str());
    

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

  • 4

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

  • 1

    在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

  • 0

    在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 如果需要解释十六进制,需要指定基数 .

  • 553

    好吧,很多答案,很多可能性 . 我在这里缺少的是一些将字符串转换为不同的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会发现这样的错误并抛出异常 .

相关问题