streambuf :: xsgetn和州旗

时间:2015-03-04 20:27:33

标签: c++ iostream

受保护的虚拟成员函数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条件?

1 个答案:

答案 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个字符。函数调用的结果由有权访问流状态的更高级流操作获取,并将相应地设置它。