97

Possible Duplicate:
How to parse a string to an int in C++?

I have done some research and some people say to use atio and others say it's bad, and I can't get it to work anyways.

So I just want to ask flat out, whats the right way to convert a string to a int.

string s = "10";
int i = s....?

Thanks!

Community
  • 1
  • 1
kralco626
  • 8,456
  • 38
  • 112
  • 169
  • 3
    you probably meant (`std::`)`string s = "10"`. – lijie Dec 14 '10 at 18:19
  • 1
    Duplicate of http://stackoverflow.com/questions/200090/how-do-you-convert-a-c-string-to-an-int and http://stackoverflow.com/questions/194465/how-to-parse-a-string-to-an-int-in-c – Adam Rosenfield Dec 14 '10 at 18:21
  • @lijie - maybe, but I never say that in my code... should I be? – kralco626 Dec 14 '10 at 18:23
  • @adam - hmm, look like great solutions, unfortunatly no stackoverflow results came up on google, and i didn't see those when I was typing in my question. – kralco626 Dec 14 '10 at 18:24
  • @kralco626: i mean the quotation marks. you want to convert the _string_ "10" into the integer 10, right? – lijie Dec 14 '10 at 18:24
  • @kralco626: yes the search isn't always that successful :/ – Matthieu M. Dec 14 '10 at 18:50
  • I suggest starting parseinttostring.stackexchange.com. It's not the depth of the answer but the number of people asking this question. – wilhelmtell Dec 14 '10 at 20:07
  • parsestringtoint.stackexchange.com or parseintfromstring.stackexchange.com you mean :) – kralco626 Dec 14 '10 at 21:34
  • wow... never had a question closed on me before... boy do I feel like a failure... – kralco626 Dec 14 '10 at 23:49
  • I'm yet to see a solution that someone has not called either inefficient or unsafe... I think the best solution is just to use Java! `int num = Integer.parseInt(new String("10"));` – kralco626 Dec 15 '10 at 15:35

5 Answers5

126
  • In C++11, use std::stoi as:

     std::string s = "10";
     int i = std::stoi(s);
    

    Note that std::stoi will throw exception of type std::invalid_argument if the conversion cannot be performed, or std::out_of_range if the conversion results in overflow(i.e when the string value is too big for int type). You can use std::stol or std:stoll though in case int seems too small for the input string.

  • In C++03/98, any of the following can be used:

     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
    

Note that the above two approaches would fail for input s = "10jh". They will return 10 instead of notifying error. So the safe and robust approach is to write your own function that parses the input string, and verify each character to check if it is digit or not, and then work accordingly. Here is one robust implemtation (untested though):

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' )
            throw std::invalid_argument("invalid input string");
          result = result * 10  - (*s - '0');  //assume negative number
          ++s;
     }
     return negate ? result : -result; //-result is positive!
} 

This solution is slightly modified version of my another solution.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 8
    In general I'd avoid `atoi` in user-provided input, since, when you get a 0, you don't know if it is because the string contained `"0"` or because it was invalid. – Matteo Italia Dec 14 '10 at 18:34
  • Atoi and itoa often cause problems so I would recommend avoiding these functions. I would use boost or stringstream instead. – RageD Dec 14 '10 at 18:35
  • good for a quick project though because of it's simplicity – kralco626 Dec 14 '10 at 21:35
  • I'm yet to see a solution that someone has not called either inefficient or unsafe... I think the best solution is just to use Java! `int num = Integer.parseInt(new String("10"));` – kralco626 Dec 15 '10 at 15:34
  • 3
    Yes Java has robust library for such common tasks. However your Java example is wrong - You shouldn't allocate new instance for string literals. – viktor Nov 09 '11 at 16:23
  • ah yes, I was thinking C# where there is a difference. – kralco626 Jan 25 '13 at 20:40
  • 2
    uh what? in C# you'd write `int.Parse("10")` (or use `TryParse` to avoid an exception) – Qwertie Nov 05 '13 at 22:09
  • BTW std::stoi doesnt work in lastest cygwin c++ compiler (as for 14NOV2015) – Stepan Yakovenko Nov 14 '15 at 11:01
14

You can use 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;
}
Eugen Constantin Dinca
  • 8,994
  • 2
  • 34
  • 51
  • 10
    boost lexical_cast is very very very slow. also they fact that it requires exception handling makes it even more cubersome to use. only good for input that comes in at user speeds, nothing else. –  Dec 15 '10 at 03:50
  • 1
    @dman: indeed lexical_cast is slower than atoi/strtol/sscanf but 1) the OP did not ask about the fastest way (and the question is tagged c++) 2) lexical_cast is generic solution and being part of Boost can tell you some things about the quality of the implementation 3) bad_lexical_cast exception provides you with a way to detect conversion errors, small price to pay for proper error handling 4) if lexical_cast your bottleneck it's pretty easy to implement a specialization for your data types – Eugen Constantin Dinca Dec 15 '10 at 15:46
  • +1 on this. I like your argument, and I actually like the solution. Being a Java person I like try catch and would likely use this solution in the future. – kralco626 Dec 16 '10 at 11:36
11

You can use istringstream.

string s = "10";

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

int i;
// use is like an input stream
is >> i;
Waqar
  • 8,558
  • 4
  • 35
  • 43
Sonny Saluja
  • 7,193
  • 2
  • 25
  • 39
9

There is no "right way". If you want a universal (but suboptimal) solution you can use a boost::lexical cast.

A common solution for C++ is to use std::ostream and << operator. You can use a stringstream and stringstream::str() method for conversion to string.

If you really require a fast mechanism (remember the 20/80 rule) you can look for a "dedicated" solution like C++ String Toolkit Library

Best Regards,
Marcin

Waqar
  • 8,558
  • 4
  • 35
  • 43
Marcin
  • 897
  • 1
  • 7
  • 19
  • 35
    "There is no'right way'" - you gotta love a language where there is no "right way" to parse a string... :( – kralco626 Dec 16 '10 at 11:34
7

Some handy quick functions (if you're not using 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;
}

Example:

int i = FromString<int>(s);
std::string str = ToString(i);

Works for any streamable types (floats etc). You'll need to #include <sstream> and possibly also #include <string>.

AshleysBrain
  • 22,335
  • 15
  • 88
  • 124
  • 3
    This is the solution boost::lexical_cast uses – Marcin Dec 18 '10 at 20:20
  • Actualla boost::lexical_cast doesn't use the original std string-streams, but some tweaked stream class that should make it a little faster than these functions. Also it includes error-checking (including the check if the input was fully consumed by the extraction operator), so it's much safer to use than those two functions. – Paul Groke Jun 25 '12 at 22:29