Hi,
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 http://stackoverflow.com/questions/149268/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.