How can I convert a std::string to int?
Solution 1
In C++11 there are some nice new convert functions from std::string
to a number type.
So instead of
atoi( str.c_str() )
you can use
std::stoi( str )
where str
is your number as std::string
.
There are version for all flavours of numbers:
long stol(string)
, float stof(string)
, double stod(string)
,...
see http://en.cppreference.com/w/cpp/string/basic_string/stol
Solution 2
The possible options are described below:
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
This is an error (also shown by cppcheck) because "scanf without field width limits can crash with huge input data on some versions of libc" (see here, and here).
2. std::sto()*
#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
}
This solution is short and elegant, but it is available only on on C++11 compliant compilers.
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 ??
However, with this solution is hard to distinguish between bad input (see here).
4. 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
}
However, this is just a wrapper of sstream
, and the documentation suggests to use sstream
for better error management (see here).
5. strto()*
This solution is very long, due to error management, and it is described here. Since no function returns a plain int, a conversion is needed in case of integer (see here for how this conversion can be achieved).
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
Conclusions
Summing up, the best solution is C++11 std::stoi()
or, as a second option, the use of Qt libraries. All other solutions are discouraged or buggy.
Solution 3
std::istringstream ss(thestring);
ss >> thevalue;
To be fully correct you'll want to check the error flags.
Solution 4
use the atoi function to convert the string to an integer:
string a = "25";
int b = atoi(a.c_str());
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Solution 5
To be more exhaustive (and as it has been requested in comments), I add the solution given by C++17 using std::from_chars
.
std::string str = "10";
int number;
std::from_chars(str.data(), str.data()+str.size(), number);
If you want to check whether the conversion was successful:
std::string str = "10";
int number;
auto [ptr, ec] = std::from_chars(str.data(), str.data()+str.size(), number);
assert(ec == std::errc{});
// ptr points to chars after read number
Moreover, to compare the performance of all these solutions, see the following quick-bench link: https://quick-bench.com/q/GBzK53Gc-YSWpEA9XskSZLU963Y
(std::from_chars
is the fastest and std::istringstream
is the slowest)
Brandon
Updated on February 15, 2022Comments
-
Brandon about 2 years
I want to convert a string to an int and I don't mean ASCII codes.
For a quick run-down, we are passed in an equation as a string. We are to break it down, format it correctly and solve the linear equations. Now, in saying that, I'm not able to convert a string to an int.
I know that the string will be in either the format (-5) or (25) etc. so it's definitely an int. But how do we extract that from a string?
One way I was thinking is running a for/while loop through the string, check for a digit, extract all the digits after that and then look to see if there was a leading '-', if there is, multiply the int by -1.
It seems a bit over complicated for such a small problem though. Any ideas?
-
Nawaz over 12 yearsThis will not extract
-5
from(-5)
. -
Winston Ewert over 12 years@Nawaz, are the parens actually there, or is that just how the OP is presenting his strings?
-
Nawaz over 12 yearsI don't know. I'm just pointing out the limitation of the approach.
-
Winston Ewert over 12 years@Nawaz, that's not really a limitation, more of preprocessing required to get rid of parens.
-
Nawaz over 12 yearsThat is what is called limitation. It cannot directly operate on input.
-
James Kanze over 12 yearsA typo. It should be simply
boost::lexical_cast<int>( theString )
(wheretheString
is the name of the variable which contains the string you want to convert toint
). -
Winston Ewert over 12 years@Nawaz, It also can't operate on the input "WERWER". I don't think the parens are actually part of his actual string and I don't think the fact that I don't parse them is relevant.
-
Nawaz over 12 yearsI said that because he used the word "extract" when he asked :
But how do we extract that from a string?
-
Winston Ewert over 12 years@Nawaz, ok... I don't take the word that way but I see how you could.
-
Yuchen almost 10 yearsThe question is about converting from
string
toint
rather than fromchar
tostring
. -
Ben Voigt about 9 yearsNever ever use
atoi
.strtol
does everythingatoi
does, but better, and fails safely. -
Ben Voigt about 9 yearsAny time you think about
atoi
, usestrtol
instead. -
CC. almost 9 yearsFor issues with std::stoi see stackoverflow.com/a/6154614/195527 : it will convert
"11x"
to integer11
. -
Yuchen about 8 yearsThe link is broken. Could you fix it?
-
Ulad Kasach about 8 years#include <stdlib.h> /* atoi */
-
Tin Wizard almost 8 years@CC That's also the behavior of atoi: cplusplus.com/reference/cstdlib/atoi "The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function."
-
caoanan about 7 yearsbuggy and not matching the question
-
Claudio almost 7 yearsFixed. Thanks for reporting.
-
luca almost 6 yearsBeautiful summary, many thanks. May I suggest to add an initial comment suggesting the final solution so that only people interested in the details keep reading?
-
NathanOliver almost 5 yearsWould you mind updating this answer with
from_chars
from C++17? It is supposed to be orders of magnitude faster thanstoi
. -
xception over 4 yearsthis should be the accepted answer, also you forgot (or rather should add cause it's an old answer) from_chars
-
phuclv over 4 years
stoi
should be preferred. See Why shouldn't I use atoi()? -
Arne about 4 yearsAny idea why there is std::stoi and std::stoul, but no std::stou or std::stoui to convert a string to unsigned int? Only to unsigned long?
-
HolyBlackCat over 3 yearsThis doesn't handle overflows or negative numbers. The second function is very similar to
atoi
, not sure why write it by hand. Also, some things could be improved: don't pass strings by value, use standard functions more (the first function could be rewritten using something likestd::all_of
+std::isdigit
). -
Jackt almost 3 yearsif returns zeo ??? you dont know if the string was actually 0 or conversion error !
-
Marc Dirven almost 3 yearsDon't use
sscanf
. It's a C API function, and the question is regarding C++. If you're planning to usesscanf
then at least usestd::
. -
cigien over 2 years
std::stoi
is already mentioned in multiple other answers, and the question is not asking about converting double to string. -
Admin over 2 yearsAs it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-
Vainstein K over 2 yearsExpanding on @BenVoigt's comment: a big reason to avoid
atoi
is that it reports conversion failure solely by returning0
!atoi
not so much fails unsafely as it fails silently. -
Ben Voigt over 2 years@VainsteinK: Some failures are reported by returning
0
. Others cause undefined behavior withatoi
. That makes it useless for validation of untrusted input. wiki.sei.cmu.edu/confluence/display/c/… -
Yongqi Z over 2 yearsBut what will you do if
std::stoi("not-a-num")
, this will casecore dumped