我有一个大文件,其中每一行都包含以空格分隔的整数。任务是逐行稀疏这个文件。对于字符串到 int 的转换,我有三种解决方案:
static int stringToIntV1(const string& str) {
return (atoi(str.c_str()));
}
但是,如果我传递格式错误的字符串,它不会产生任何错误。例如字符串“123error”被转换为 123。
第二种方案:
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!");
}
我这里有同样的问题,格式错误的字符串不会引发错误。
Boost 的第三个解决方案(在 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;
}
这个给出了正确的结果。
但是,执行时间有显着差异。在大型文本文件 (32 MB) 上进行测试,我得到了以下时间:
- (1) 使用 atoi:4.522s(获胜者)
- (2) with istringstream:15.303s(非常慢)
- (3) with lexical_cast:10.958s(两者之间)
我的问题:您知道如何使用 atoi 发现格式错误的字符串吗?它将提供最快的解决方案。或者您知道更好的解决方案吗?
更新:感谢您的回答。按照提示,我想出了这个解决方案:
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!");
}
好消息是,如果出现问题,它会产生并且与atoi
版本一样高效。
最佳答案
我会使用 strtol
。它采用一个参数,该参数设置为指向它无法转换的第一个字符,因此您可以使用它来确定整个字符串是否已转换。
编辑:就速度而言,我预计它会比 atoi
稍慢,但比您尝试过的其他速度要快。
关于c++ - 将字符串转换为 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2023519/