0

众所周知,cin 不是类型安全的(例如 cin >> integer;输入“55”会导致它翻转)。我见过许多不太优雅的处理方法,例如获取字符串并使用 sstream 将其转换为数字,或使用 cin.fail() 循环并清除流并重新输入等。有没有库或无论如何重载提取运算符以使 cin 自动类型安全?

4

5 回答 5

13

例如cin >> integer;,输入“五十五”将导致它翻转

不,这不会导致它“翻转”;它将导致设置流的失败状态,就像任何其他流一样。这并不意味着它std::cin不是类型安全的。

处理从流中读取的错误的一种选择是编写一个函数模板来执行提取,测试它是否成功,在适当的情况下重置流上的错误状态,并返回提取是否成功以及结果。

于 2010-06-08T03:04:03.137 回答
4

众所周知,cin 不是类型安全的(例如 cin >> integer;输入“55”会导致它翻转)。

类型安全并不意味着您似乎认为它意味着什么。“五十五”是一个字符串。将它安全地转换为数字是一个复杂的问题,如果你真的想要一个通用/便携的实现(如果它是“cinquante-cinq”[法语]或“femtifem”[挪威语])?你必须考虑语言、词法解析、语法正确性等等。这远远超出了 STL 的范围。

std::istream 从某种意义上说是类型安全的,如果您尝试给出的示例,流将识别错误(“知道”它不能将流解释为整数)并以可以检查的方式向您的客户端代码发出错误信号并在客户端代码中处理。

作为比较,如果您使用int i; sscanf("fifty five", "%s", &i);它可能不会引发任何错误,请i用垃圾填充您的程序,如果它取决于是否i具有有效值,您的程序可能会在稍后崩溃(我可能错了 - 我没有使用过sscanf,因为高-学校左右)。或者,如果您的格式请求与输入字符串的内容不匹配,它可能会损坏程序的内存。

于 2010-06-08T08:42:24.167 回答
1

例如 cin >> 整数;并输入“五十五”将导致它翻转
[...]
是否有任何库或无论如何重载提取运算符以使 cin 自动类型安全?

所以std::cin当你想从中读取错误的对象时失败。
有趣的是,在这里我一直认为,如果您尝试读取错误的类型,则读取失败的事实使它成为 type-safe

无论如何,既然你碰巧不同意,你会建议哪种行为呢?

于 2010-06-08T06:47:55.927 回答
0

你可以有一个带有“类型”字段的结构和一个包含字符串、双精度、布尔和整数的联合字段。然后你可以编写一个 operator>> (ostream &, youtype &) 重载,它首先从 ostream 读取字符串并尝试将其转换为最具体的类型(“1”变成 int,“1.0”变成 double 等等... ),相应地设置“类型”字段。

这不是一个完美的解决方案,但应该可以相当容易地在其他项目中重用。

于 2010-06-08T03:43:22.163 回答
0

异常处理。这将防止您的示例“翻转[ping]”。

于 2010-06-08T03:58:51.147 回答