自定义std::fstream,std::filebuf的溢出和下溢函数不为每个字符调用。

问题描述 投票:4回答:1

我想做一个自定义的std::fstream,在读取时对数据进行编码。

template <class T>
class _filebuf : public std::filebuf {
public:
    using transform_type = T;

    int_type underflow() override {
        auto c = std::filebuf::underflow();
        return c < 0 ? c : transform.decode(c);
    }

    int_type overflow(int_type c) override {
        return c < 0 ? c : std::filebuf::overflow(transform.encode(c));
    }

private:
    transform_type transform;
};

template <class T>
class _fstream : public std::iostream {
public:
    using buffer_type = _filebuf<T>;

    explicit _fstream(const std::string& path, std::ios::openmode openmode)
        : std::iostream(0)
    {
        this->init(&buffer);
        buffer.open(path, openmode);
    }

private:
    buffer_type buffer;
};

有一个使用实例

class _transform {
public:
    template <class T>
    T encode(T value) const {
        return value - 1;
    }

    template <class T>
    T decode(T value) const {
        return value + 1;
    }    
};

int main() {
    _fstream<_transform> ofs("test.txt", std::ios::out | std::ios::trunc);
    ofs << "ABC"; // outputs "@BC" to the file (@ is 64 in ASCII, so only first character encoded properly)

    _fstream<_transform> ifs("test.txt", std::ios::in);
    std::string s;
    ifs >> s; // inputs  "ABC" when "@BC" was in the file so again only first character is decoded

    // ...
};

经过我自己的研究,我发现 溢出 函数在这个过程中被调用两次(用 65和-1,其中-1可能是EOF)和 '下流' 并两次 64和-1). 由于其他字符没有丢失,它们可能在没有调用这些函数的情况下以某种方式进行了处理。

为什么会发生这种情况,如何改变它?

c++ inheritance c++17 fstream iostream
1个回答
1
投票

std::streambuf<CharT,Traits>::underflow 确保 至少一个 字符在get区域中是可用的,有效的实现了。std::filebuf 将始终尝试将一个完整的缓冲区的字符读取到get区域。除非你寻求流 underflow 将不会被再次调用,直到get区域被调用到的 sgetnxsgetnsbumpc

我想你可能会有更多的成功包装而不是扩展文件缓冲区。

提升 iostreams 使得编写流过滤器变得更加简单。

© www.soinside.com 2019 - 2024. All rights reserved.