【发布时间】:2012-02-29 19:16:15
【问题描述】:
这段代码永远循环:
#include <iostream>
#include <fstream>
#include <sstream>
int main(int argc, char *argv[])
{
std::ifstream f(argv[1]);
std::ostringstream ostr;
while(f && !f.eof())
{
char b[5000];
std::size_t read = f.readsome(b, sizeof b);
std::cerr << "Read: " << read << " bytes" << std::endl;
ostr.write(b, read);
}
}
这是因为readsome 永远不会设置eofbit。
通过修改内部状态标志来发出错误信号:
eofbit获取指针位于流缓冲区内部输入的末尾 调用函数时的数组,这意味着没有位置可以 读取内部缓冲区(可能是也可能不是输入的结尾 顺序)。当rdbuf()->in_avail()在 提取第一个字符。
failbit流位于字符源的末尾 函数被调用。
badbit发生了上述以外的错误。
几乎一样,标准说:
[C++11: 27.7.2.3]:streamsize readsome(char_type* s, streamsize n);32.效果: 表现为一个未格式化的输入函数(如在 27.7.2.3,第 1 段)。构造哨兵对象后,如果
!good()调用setstate(failbit)可能会抛出异常并返回。否则提取 字符并将它们存储到数组的连续位置中,其第一个 元素由s指定。如果rdbuf()->in_avail() == -1,则调用setstate(eofbit)(可能会抛出ios_base::failure(27.5.5.4)),并提取 没有字符;
- 如果
rdbuf()->in_avail() == 0,则不提取字符- 如果
rdbuf()->in_avail() > 0,提取min(rdbuf()->in_avail(),n))。33.返回:提取的字符数。
in_avail() == 0 条件是空操作意味着如果流缓冲区为空,ifstream::readsome 本身就是空操作,但 in_avail() == -1 条件意味着它将设置eofbit 当其他一些操作导致in_avail() == -1。
尽管readsome 具有“某种”性质,这似乎是不一致的。
那么readsome 和eof 的语义是什么?我是否正确解释了它们?它们是流库中设计不佳的示例吗?
(从 [IMO] 盗取无效libstdc++ bug 52169。)
【问题讨论】: