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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With