Reputation: 11409
I have the following string:
sThis = "2154910440";
unsigned int iStart=atoi(sThis.c_str());
However the result is
iStart = 2147483647
Does anybody see my mistake?
Upvotes: 24
Views: 103096
Reputation: 13
This code will convert it with C++11:
std::string sThis = "2154910440";
unsigned int iStart = static_cast<unsigned int>(std::stoul(sThis));
std::stoul
will return an unsigned long
, which is larger than an unsigned int
.
static_cast
will convert it to the right type.
Upvotes: 1
Reputation: 1590
Unfortunately C++ has no embedded implementation for parsing unsigned int and this is really strange.
Here is a code which can help you:
#include <stdint.h>
#include <sstream>
inline unsigned int stoui(const std::string& s)
{
std::istringstream reader(s);
unsigned int val = 0;
reader >> val;
return val;
}
// This may be not the same as stoui on some platforms:
inline uint32_t stoui32(const std::string& s)
{
std::istringstream reader(s);
uint32_t val = 0;
reader >> val;
return val;
}
Upvotes: 1
Reputation: 283793
You should instead use std::strtoul
, found in <cstdlib>
, which is designed for unsigned numbers, has a larger range, and reports errors better.
If you want to use std::string
for input and exceptions for error handling, use std::stoul
. A short, highly efficient implementation would be as follows:
#include <string>
#include <stdexcept>
inline unsigned int stoui(const std::string& s)
{
unsigned long lresult = stoul(s, 0, 10);
unsigned int result = lresult;
if (result != lresult) throw std::out_of_range();
return result;
}
This will be much faster than istringstream
, culture-invariant (so no unexpected changes to behavior when run in an unusual locale), completely portable, and using the third argument, you can support different numeric bases or even perform detection of 0x
and 0
prefixes.
But unsigned int
isn't necessarily big enough to hold your value, so use unsigned long
, and then you won't need the above wrapper.
Upvotes: 16
Reputation: 876
you can use atol which convert string to long int . To read more see the man atol in Linux.
the prototype
#include <stdlib.h>
long atol(const char *nptr);
Upvotes: 1
Reputation: 103741
atoi
converts a string to an int
. On your system, an int
is 32 bits, and its max value is 2147483647. The value you are trying to convert falls outside this range, so the return value of atoi
is undefined. Your implementation, I guess, returns the max value of an int
in this case.
You could instead use atoll
, which returns a long long, which is guaranteed to be at least 64 bits. Or you could use a function from the stoi/stol/stoll
family, or their unsigned counterparts, which will actually give useful error reports on out of range values (and invalid values) in the form of exceptions.
Personally, I like boost::lexical_cast
. Even though it appears a bit cumbersome, it can be used in a more general context. You can use it in templates and just forward the type argument instead of having to have specializations
Upvotes: 46
Reputation: 39859
Don't forget, you can always write your own function that does exactly what you want.
This code will work with any number between -9223372036854775806 (2^63+1) and 9223372036854775807 (2^63-1) inclusive.
Something like this:
long long int myAtoi ( string str ) {
long long int value = 0;
for (int i = 0; i < str.size(); i++) {
if (str[i] != '-') {
value *= 10;
value += (int) ((str[i]) - '0');
}
}
if (str.size() > 0 && str[0] == '-')
return -value;
else
return value;
}
Upvotes: 2
Reputation: 1399
An unsigned int is often a 32 bit value in C++ which has a maximum of 4,294,967,295. 2,154,710,440 can therefore be represented as an unsigned int. However, atoi converts to an int which is signed and has a maximum value of 2,147,483,647 - so you string overflows the value range whichis why your answer is incorrect. You could use atoll which converts your string to a long long which will be at least 64 bits. Integer sizes are compiler dependent in C++. It is often better to include the header file stdint.h and then use uint32_t or uint64_t and so on, so that you know the size you are dealing with.
Upvotes: 1
Reputation: 10939
atoi returns a signed int, which on your platform has a max value of 2^31-1
.
It doesn't matter what you're assigning that result to, it will be bounded by the return type.
C++ streams can read unsigned ints.
std::istringstream reader(sThis);
unsigned int val;
reader >> val;
Upvotes: 11