【问题标题】:What could cause a stream to enter the "bad" state?什么可能导致流进入“坏”状态?
【发布时间】:2012-08-23 02:33:41
【问题描述】:

在 C++ 中,每个流都有一个 bad 位:

此标志由在读取或写入数据时发生错误时对流执行的操作设置,通常会导致流的完整性丢失。

Source

什么会导致流“失去完整性”并进入bad 状态?这与fail 状态不同,这通常发生在输入流尝试将值存储到无法接受所述值的变量中(例如尝试将字符串存储到整数变量中)。

请注意,这个问题是c++ file bad bit 的更一般形式,专门针对文件输入流;这个问题并不完全重复,因为它通常适用于输入和输出流。

【问题讨论】:

  • 可能是遇到无效多字节序列的多字节编码流?
  • @KerrekSB,这可能会设置fail 位,而不是bad 位,因为流可以由ios::clear()ios::ignore() 恢复。这只是无效输入的情况;我认为这不会导致流失去完整性。

标签: c++ stream iostream


【解决方案1】:

根据cppreference.com

标准库在以下情况下设置badbit:

  • put()write() 插入输出流失败 原因。

  • 通过operator<<std::put_money 或插入输出流 std::put_time,无法完成,因为输出结束 已到达流(构面的格式化输出函数,例如 num_put::put()money_put::put(),返回一个迭代器 iter 这样 iter.failed()==true)

  • Stream 是用 rdbuf() 的空指针构造的,或者 putback()/unget() 在带有空 rdbuf() 的流上调用,或者 空指针传递给operator<<(basic_streambuf*)

  • rdbuf()->sputbackc()rdbuf()->sungetc() 返回 traits::eof()putback() orunget()`

  • rdbuf()->pubsync() 将 -1 返回到 sync()flush()unitbuf 流上 ostream::sentry 的析构函数

  • 的任何成员函数在 I/O 操作期间引发异常 关联的流缓冲区(例如sbumpc()xsputn()sgetc()overflow()等)

  • iword()pword() 中抛出异常(例如std::bad_alloc


这可能是选择 cppreference.com 而不是 www.cpluplus.com 的另一个原因,请参阅: What's wrong with cplusplus.com?

【讨论】:

  • “底层 I/O 操作中的异常”听起来不错。毕竟,iostream 是为了扩展而设计的,因此完全可以想象,某些用户提供的实现会在更深层次抛出异常。
  • “意图”是让badbit 发出实际输入/输出错误的信号。但是,std::streambuf 的接口不允许这样做;它要么返回char 要么返回EOF。如果在读取 std::filebuf 时遇到输入错误(read 在 Posix 下返回 -1),我希望 std::filebuf 会引发异常,因为它没有其他方法可以发出错误信号。
【解决方案2】:

看看Apache C++ Standard Library User's Guide。那里列出了两个潜在的错误原因。我引用:

内存不足:没有可用于创建缓冲区的内存,或者由于其他原因(例如从流外部提供),缓冲区的大小为 0,或者流无法为它自己的内部数据。

底层流缓冲区抛出异常:流缓冲区可能会失去完整性,例如内存不足、代码转换失败或来自外部设备的不可恢复的读取错误。流缓冲区可以通过抛出异常来指示这种完整性丢失,该异常被流捕获并导致在流的状态中设置坏位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    相关资源
    最近更新 更多