c ++从字符串解析int

kra*_*626 78 c++ string int

可能重复:
如何在C++中将字符串解析为int?

我做了一些研究,有些人说使用atio而其他人说它很糟糕,我无论如何也无法让它工作.

所以我只想问一下,将字符串转换为int的正确方法是什么.

string s = "10";
int i = s....?
Run Code Online (Sandbox Code Playgroud)

谢谢!

Naw*_*waz 90

  • 在C++ 11中,std::stoi用作:

    std::string s = "10";
    int i = std::stoi(s);
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,如果无法执行转换,或者转换导致溢出(即字符串值对于类型来说太大),std::stoi将抛出类型异常.您可以使用或尽管看起来输入字符串太小.std::invalid_argumentstd::out_of_rangeintstd::stolstd:stollint

  • 在C++ 03/98中,可以使用以下任何一种方法:

    std::string s = "10";
    int i;
    
    //approach one
    std::istringstream(s) >> i; //i is 10 after this
    
    //approach two
    sscanf(s.c_str(), "%d", &i); //i is 10 after this
    
    Run Code Online (Sandbox Code Playgroud)

请注意,上述两种方法无法输入s = "10jh".他们将返回10而不是通知错误.因此,安全可靠的方法是编写自己的函数来解析输入字符串,并验证每个字符以检查它是否为数字,然后相应地工作.这是一个强大的实现(虽然未经测试):

int to_int(char const *s)
{
     if ( s == NULL || *s == '\0' )
        throw std::invalid_argument("null or empty string argument");

     bool negate = (s[0] == '-');
     if ( *s == '+' || *s == '-' ) 
         ++s;

     if ( *s == '\0')
        throw std::invalid_argument("sign character only.");

     int result = 0;
     while(*s)
     {
          if ( *s >= '0' && *s <= '9' )
          {
              result = result * 10  - (*s - '0');  //assume negative number
          }
          else
              throw std::invalid_argument("invalid input string");
          ++s;
     }
     return negate ? result : -result; //-result is positive!
} 
Run Code Online (Sandbox Code Playgroud)

这个解决方案稍微修改了我的另一个解决方案.

  • 一般来说,我会在用户提供的输入中避免使用`atoi`,因为当你得到一个0时,你不知道是不是因为字符串包含"0"或者因为它是无效的. (6认同)
  • 是Java为这些常见任务提供了强大的库.但是您的Java示例是错误的 - 您不应该为字符串文字分配新实例. (3认同)
  • 呃什么?在 C# 中,您可以编写 `int.Parse("10")` (或使用 `TryParse` 来避免异常) (2认同)

Eug*_*nca 13

你可以使用boost :: lexical_cast:

#include <iostream>
#include <boost/lexical_cast.hpp>

int main( int argc, char* argv[] ){
std::string s1 = "10";
std::string s2 = "abc";
int i;

   try   {
      i = boost::lexical_cast<int>( s1 );
   }
   catch( boost::bad_lexical_cast & e ){
      std::cout << "Exception caught : " << e.what() << std::endl;
   }

   try   {
      i = boost::lexical_cast<int>( s2 );
   }
   catch( boost::bad_lexical_cast & e ){
      std::cout << "Exception caught : " << e.what() << std::endl;
   }

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • boost lexical_cast非常非常慢.事实上,它需要异常处理才能使其更加立体化.仅适用于以用户速度输入的输入,没有别的. (9认同)

Mar*_*cin 9

没有"正确的方法".如果你想要一个通用(但次优)解决方案,你可以使用boost :: lexical cast.

C++的常见解决方案是使用std :: ostream和<<运算符.您可以使用stringstream和stringstream :: str()方法转换为字符串.

如果你真的需要一个快速机制(记住20/80规则),你可以寻找像http://www.partow.net/programming/strtk/index.html这样的"专用"解决方案.

最诚挚的问候,
Marcin

  • "没有'正确的方式'" - 你必须喜欢一种语言,其中没有"正确的方法"来解析字符串... :( (25认同)

San*_*uja 7

你可以使用istringstream.

string s = "10";

// create an input stream with your string.
istringstream is(str);

int i;
// use is like an input stream
is >> i;
Run Code Online (Sandbox Code Playgroud)


Ash*_*ain 5

一些方便的快速功能(如果您不使用 Boost):

template<typename T>
std::string ToString(const T& v)
{
    std::ostringstream ss;
    ss << v;
    return ss.str();
}

template<typename T>
T FromString(const std::string& str)
{
    std::istringstream ss(str);
    T ret;
    ss >> ret;
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

例子:

int i = FromString<int>(s);
std::string str = ToString(i);
Run Code Online (Sandbox Code Playgroud)

适用于任何可流式传输类型(浮点数等)。您需要#include <sstream>并且可能还需要#include <string>

  • 这是 boost::lexical_cast 使用的解决方案 (3认同)