gpt4 book ai didi

c++ - `ifstream::readsome` 什么时候设置 `eofbit` ?

转载 作者:可可西里 更新时间:2023-11-01 16:38:58 26 4
gpt4 key购买 nike

这段代码永远循环:

#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

cplusplus.com说:

Errors are signaled by modifying the internal state flags:

eofbit The get pointer is at the end of the stream buffer's internal input array when the function is called, meaning that there are no positions to be read in the internal buffer (which may or not be the end of the input sequence). This happens when rdbuf()->in_avail() would return -1 before the first character is extracted.

failbit The stream was at the end of the source of characters before the function was called.

badbit An error other than the above happened.

几乎一样,标准说:

[C++11: 27.7.2.3]: streamsize readsome(char_type* s, streamsize n);

32. Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After constructing a sentry object, if !good() calls setstate(failbit) which may throw an exception, and return. Otherwise extracts characters and stores them into successive locations of an array whose first element is designated by s. If rdbuf()->in_avail() == -1, calls setstate(eofbit) (which may throw ios_base::failure (27.5.5.4)), and extracts no characters;

  • If rdbuf()->in_avail() == 0, extracts no characters
  • If rdbuf()->in_avail() > 0, extracts min(rdbuf()->in_avail(),n)).

33. Returns: The number of characters extracted.

in_avail() == 0 条件是空操作意味着如果流缓冲区为空,则 ifstream::readsome 本身是空操作,但是 in_avail() == -1 条件意味着它设置 eofbit一些其他操作导致到 in_avail() == -1

尽管 readsome 具有“某些”性质,但这似乎是一种不一致。

那么 readsomeeof 的语义是什么?我对它们的解释是否正确?它们是流库中设计不佳的例子吗?


(从 [IMO] 中盗取无效 libstdc++ bug 52169 .)

最佳答案

我认为这是一个自定义点,默认流实现并未真正使用它。

in_avail() 返回它在内部缓冲区中可以看到的字符数(如果有的话)。否则它会调用 showmanyc() 来尝试检测字符是否已知在其他地方可用,因此缓冲区填充请求一定会成功。

反过来,showmanyc() 将返回它知道的字符数(如果有的话),或者 -1 如果它知道读取将失败,或者 0如果它没有线索。

默认实现 (basic_streambuf) 总是返回 0,所以这就是你得到的结果,除非你有一个流与一些其他 streambuf 覆盖 showmanyc

您的循环本质上是按您所知道的那样安全读取多个字符,当它为零(意思是“不确定”)时会卡住。

关于c++ - `ifstream::readsome` 什么时候设置 `eofbit` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9191876/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com