你如何使cin类型安全?

时间:2010-06-08 02:59:20

标签: c++ cin

众所周知,cin不是类型安全的(例如cin>>整数;输入“五十五”会导致它翻转)。我已经看到了许多不那么优雅的方法来处理这个问题,例如getlining一个字符串并使用sstream将其转换为数字,或者使用cin.fail()循环并清除流并重新输入它等等。有没有库或者无论如何重载提取操作符以使cin自动类型安全?

5 个答案:

答案 0 :(得分:13)

  

e.g。 cin >> integer;并输入“五十五”将导致其翻转

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

处理从流中读取错误的一个选项是编写执行提取的函数模板,测试它是否成功,如果合适则重置流上的错误状态,并返回提取是否与结果一起成功。

答案 1 :(得分:4)

  

众所周知,cin不是   typesafe(例如cin>>整数;和   进入“五十五”将导致它   翻出来。)

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

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

作为比较,如果您使用int i; sscanf("fifty five", "%s", &i);这可能不会引发任何错误,请将您的i填入垃圾邮件,如果某个程序取决于i有效价值(我可能错了 - 自高中以来我没有使用过sscanf)。或者,如果您的格式请求与输入字符串的内容不匹配,则可能会破坏程序的内存。

答案 2 :(得分:1)

  

e.g。 cin>>整数;进入“五十五”将导致它翻转出来   [...]
  是否有任何库或反正过度提取操作符使cin自动类型安全?

因此当您想从中读取错误的对象时,std::cin会失败 有趣的是,在这里,我总是认为 如果你试图读错了类型就读取失败的原因是什么使它成为类型安全的

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

答案 3 :(得分:0)

你可以有一个带有'Type'字段的结构和一个包含string,double,bool和int的union字段。然后你可以写一个运算符>> (ostream&,youtype&)重载首先从ostream中读取字符串并尝试将其转换为最具体的类型(“1”变为int,“1.0”变为double,依此类推......),设置相应的“类型”字段。

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

答案 4 :(得分:0)

异常处理。这将阻止你的例子“翻转[ping] out。”