在C和C中有多种方法可以将字符串转换为整数,但是我没有找到在解析浮点数时失败的转换方法 .
const float fnum = std::stof("1.5");
std::cout << fnum << std::endl; // prints "1.5", all okay
const int inum = std::stoi("1.5");
std::cout << inum << std::endl; // prints "1", but wrong!
我需要这个来分析CSV文件的列类型 . 如果一列中的所有字段都是整数,则将列存储为std :: vector <int>,如果是float,则存储为std :: vector <float>,否则将其存储为字符串 .
看起来很有希望的唯一方法是:
std::string num = "1.5";
char *end = nullptr;
const long lnum = strtol(num.data(), &end, 10);
if (end != &*num.end()) {
std::cout << "Float? " << l << " / " << num << std::endl;
} else {
std::cout << "Integer! " << l << " / " << num << std::endl;
}
这有效,但非常难看 . 有没有解决这个问题的方法?
5 回答
你可以使用boost lexical_cast . 如果强制转换失败,它会抛出异常
您应该迭代检查数字是否解析为1)作为整数,2)作为浮点数,最后3)解析为否 . 但“解析”应该意味着消耗整个字符串 .
尝试这样的事情:
同样适用于花车 .
如果你不喜欢使用iostreams,你也可以使用
std::strtoll
和std::strtod
等 . 这样你也可以控制整数 . 例如:然后你仍然需要将它与检查所有字段的逻辑结合起来 .
例如:
使用普通的std :: stoi,但一定要检查字符串是否完全耗尽 . 例如 . :
此代码的执行速度比std :: istringstream解决方案快得多 .
如果您需要更多类型检查,请查看boost Spirit X3 . 你可以这样做:
注意:您可以指定更严格的解析(请看这里:https://github.com/djowel/spirit_x3/tree/master/include/boost/spirit/home/x3/numeric)
您希望对包含十进制数的数字失败 . 您可以测试点,也可以测试十进制数字 .
第二种选择:
您不应该担心浮点舍入错误,因为每个整数可以精确地表示为加倍到2 ^ 53 .