Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert a string to int

I have a large file where each line contains space-separated integers. The task is to sparse this file line-by-line. For the string to int conversion I have three solutions:

static int stringToIntV1(const string& str) {
    return (atoi(str.c_str()));
}

However, if I pass a malformed string, it doesn't produce any error. For instance the string "123error" is converted to 123.

Second solution:

static int stringToIntV2(const string& str)
{
    int result;
    istringstream myStream(str);

    if (myStream >> result) {
        return result;
    }
    // else
    throw domain_error(str + " is not an int!");
}

I have the same problem here, malformed strings don't raise an error.

Third solution with Boost (found at Boost Library):

static int stringToIntV3(const string& str)
{
    int iResult = 0;
    try {
        iResult = lexical_cast<int>(str);
    }
    catch(bad_lexical_cast &) {
        throw domain_error(str + " is not an int!");
    }
    return iResult;
}

This one gives correct result.

However, there is a significant difference in the execution time. Testing on a large text file (32 MB), I got the following times:

  • (1) with atoi: 4.522s (winner)
  • (2) with istringstream: 15.303s (very slow)
  • (3) with lexical_cast: 10.958s (between the two)

My question: do you know how to notice malformed strings with atoi? It would give the fastest solution. Or do you know a better solution?

Update: Thanks for the answers. Following the tips, I came up with this solution:

static int stringToIntV4(const string& str)
{
    char * pEnd;
    const char * c_str = str.c_str();
    int result = strtol(c_str, &pEnd, 10);
    if (pEnd == c_str+str.length()) {
        return result;
    }
    // else
    throw domain_error("'" + str + "'" + " is not an int!");
}

The good news is that it yields if there is a problem and as efficient as the atoi version.

like image 610
Jabba Avatar asked Dec 02 '22 06:12

Jabba


1 Answers

I'd use strtol. It takes a parameter that it sets to point at the first character it couldn't convert, so you can use that to determine whether the entire string was converted.

Edit: as far as speed goes, I'd expect it to be slightly slower than atoi, but faster than the others you tried.

like image 77
Jerry Coffin Avatar answered Dec 04 '22 10:12

Jerry Coffin