我刚刚发现(让我很惊讶)以下输入不会导致std::stoi
抛出异常:
3.14
3.14helloworld
违反了最小惊讶原则-因为这些都不是有效的整数格式值。
请注意,更令人惊讶的是,3.8
被转换为值3
。
是否有一个更严格的std::stoi
版本,当输入确实无效时会抛出异常?还是我必须自己编写?
另外,为什么C++标准库要以这种方式实现 std::stoi
?这个函数唯一的实际用途是在随机垃圾输入中拼命尝试获取一些整数值-这似乎不是一个非常有用的函数。
这是我的解决方法。
static int convertToInt(const std::string& value)
{
std::size_t index;
int converted_value{std::stoi(value, &index)};
if(index != value.size())
{
throw std::runtime_error("Bad format input");
}
return converted_value;
}
stoi
和相关函数的行为就像输入操作一样。如果你有int foo; cin >> foo;
并输入3.14
作为输入,你会在foo
中得到3
,正如使用stoi
时一样。你可以使用stoi
的第二个参数来确认是否所有的输入都被转换或者没有。 - NathanOliversize_t*
类型的参数吗?你尝试过在指向的size_t
变量中检查值吗?你明白这个和所进行的转换有什么关系吗?如果不理解,是否尝试查阅文档以便了解呢? - Karl Knechtelstd::stoi
中被忽略),但在结尾处抛出异常。因此,在抛出异常之前,你可能需要使用std::isspace
测试结尾处的输入。查看我的另一个答案的示例,了解如何操作。 - Andreas Wenzelstd::isspace
测试尾随输入-即使对于大多数人来说,这也不够严格,例如在“3 hello”中,报告的位置将是空格,但不是尾随空格。相反,我会从报告的位置开始,并使用string::find_first_not_of()
或std::find_if()
检查输入字符串中是否有任何未解析的非空白字符,然后如果发现任何未解析的字符,则抛出异常。 - Remy Lebeau