【问题标题】:How do you make cin typesafe?你如何使 cin 类型安全?
【发布时间】:2010-06-08 02:59:19
【问题描述】:

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

【问题讨论】:

  • 我想您可以尝试输入检查提供字符的内容。哦……它的用户?没关系:-)
  • 这个问题是真的吗?听起来它打算做的只是引诱一场火焰战争。

标签: c++ cin


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    作为比较,如果你使用int i; sscanf("fifty five", "%s", &i);,这可能不会引发任何错误,用垃圾填充你的i,如果它依赖于i具有有效值,你的程序可能会在稍后崩溃(我可能是这是错误的——我从高中起就没有使用过sscanf)。或者,如果您的格式请求与输入字符串的内容不匹配,它可能会损坏程序的内存。

    【讨论】:

      【解决方案3】:

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

      所以当您想从中读取错误的对象时,std::cin 会失败。
      有趣的是,在这里我一直认为 如果您尝试读取错误的类型会导致读取失败,这使得它是类型安全的

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2021-10-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-03
            • 1970-01-01
            相关资源
            最近更新 更多