2

I'm trying to convert a string variable, which contains alphabetic and numeric values, into an int variable.

string argument = "100km";
int i = atoi(argument.c_str());
cout<<i<<endl;

I've confirmed that i has an int of 100 and km is omitted. However, if I enter 2147483648km, which is over that range of int, i will have -2147483648.

According to this page, int is supposed to be able to have

–2,147,483,648 to 2,147,483,647

So, I thought that this error came from the range of int, but the same error happens even when atoi is replaced by atol and int is replaced by unsigned long, which can have a much larger value. In other words, replacing int with long doesn't fix this error.

Chances are that I need to come up with an alternative way to convert this kind of string (i.e. string of "______km" into an int variable).

3
  • 1
    According to the page that you linked, long also has the range –2,147,483,648 to 2,147,483,647 (on that platform)... Commented Jun 9, 2015 at 8:41
  • data type limits aside, I would use sscanf for this type of string parsing not atoi/atol. It's much more versatile. Commented Jun 9, 2015 at 8:44
  • Thank you all very much. Using atoll and long long seems to be the most suitable choice for my case, but other opinions are highly appreciated and informative too. Commented Jun 9, 2015 at 8:53

5 Answers 5

4

In some compilers int is not "much less" than long, and indeed they're equal.

The only guarantee the standard gives you is that a long is never smaller than an int.

A simple solution would be to use atof instead that uses doubles that on most platforms is a 64-bit IEE754 double-precision number that is able to represent all integers exactly up to a magnitude of 253 that is 9,007,199,254,740,992.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for quoting the standard on long never being less than int.
2

The size and range of the basic integer types depends on the compiler. On 32-bit platforms just about all compilers only have 32-bit int and long types. On 64-bit platforms the Visual Studio compiler still have 32-bit int and long while e.g. GCC have 32-bit int and 64-bit long.

If you want a larger type then you need long long which currently is 64 bits on all platforms and compilers (though it don't have to be).

Also, you should switch to stoi, stol and stoll (or their unsigned variants) instead of atoi.


If you want to know the actual limits, sizes and ranges of a type, you should use std::numeric_limits.

Comments

1

The data type ranges from Microsoft's site can show you what Visual C++ compilers use.
This may vary, see 6502's answer covering that.

Moreover, atol returns a long, so if you give it a unsigned long you're going to get a long in return.

Since C++11, you are able to use atoll which returns a long long, otherwise see the other answers using stoi, stol, stoll.

Comments

0

By using strtol you can achieve what you are looking for:

    string argument = "2147483648km";
    char *end;
    std::cout<<strtol(static_cast<const char *> (argument.c_str()),&end,10);

Depends on the size , you can prefer stol,stoll or stoi. More details are available here : http://en.cppreference.com/w/cpp/string/byte/strtol

Comments

0

Use std::stringstream.

#include <sstream>
#include <iostream>
#include <string>
using namespace std;

int main()
{
        std::stringstream ss { "2147483648km" };
        int n;
        string s;

        if (!(ss >> n ))
        {
                std::cout << "cannot convert \n";
        }
        else
        {
                ss >> s ;
                std::cout << n << " " << s << "\n";
        }
}

And you can even abstract the whole thing

struct Distance
{
    string unit; 
    int distance;

    friend istream& operator>>(istream& in, Distance &d)
    {
         return in >> distance >> unit;
    }

};

std::stringstream ss { "331104km" };
Distance dst;
ss >> dst;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.