受保护的虚拟成员函数streambuf::xsgetn
使I / O流实现者能够定义一个从输入流中提取n
个字符并将其存储在缓冲区中的函数。
通常,对于大多数标准流(如fstream
),此函数只需在循环中调用sbumpc
,直到返回eof
为止。但是自定义流类可以覆盖此函数以执行更高效的操作,例如将数据批量复制到输出缓冲区中。
但我不明白的是xsgetn
表示已达到EOF条件的方式。假设用户请求读取100个字节,但流中只剩下50个字节。据推测,xsgetn
应读取50个字节,返回50
,然后将内部流状态设置为eof
。
xsget
除外是streambuf
的成员函数,并且无法设置流状态。与sbumpc
不同,EOF
可以返回xsgetn
,xsgetn无法指示发生了EOF条件。那么{{1}}应该如何处理EOF条件?
答案 0 :(得分:1)
这是我在libstdc ++上找到的:
template<typename _CharT, typename _Traits>
streamsize basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) {
streamsize __ret = 0;
while (__ret < __n) {
const streamsize __buf_len = this->egptr() - this->gptr();
if (__buf_len) {
const streamsize __remaining = __n - __ret;
const streamsize __len = std::min(__buf_len, __remaining);
traits_type::copy(__s, this->gptr(), __len);
__ret += __len;
__s += __len;
this->__safe_gbump(__len);
}
if (__ret < __n) {
const int_type __c = this->uflow();
if (!traits_type::eq_int_type(__c, traits_type::eof())) {
traits_type::assign(*__s++, traits_type::to_char_type(__c));
++__ret;
} else
break;
}
}
return __ret;
}
当提取的字符小于请求的字符数时,此函数调用uflow()
以获取更多字符。如果该函数返回Traits::eof()
,则它将返回是否提取0个字符。函数调用的结果由有权访问流状态的更高级流操作获取,并将相应地设置它。