Implementing std::basic_streambuf subclass for manipulating input

c++, streambuf

Solution

underflow() has post-conditions that you failed to establish: by the time you return from it, you need to have a get area in your streambuf that holds that character you're returning.

A single-character buffer is sufficient:

    protected:
        virtual int underflow()
        {
            ch = std::tolower(m_realBuffer.sbumpc());
  +         setg(&ch, &ch, &ch+1); 
            return ch;
        }
    private:
  +     char ch; // input buffer!
        std::streambuf &m_realBuffer;
};

Problem

I have a `std::basic_streambuf` subclass that causes all output to be written in uppercase, like this: ``` class upper_streambuf : public std::streambuf { public: upper_streambuf(std::streambuf &real) : m_realBuffer(real) { } protected: virtual int overflow(int c) { int uc = std::toupper(c); m_realBuffer.sputc(uc); return uc; } private: std::streambuf &m_realBuffer; }; ``` I use it like this for example (which seems to work OK): ``` upper_streambuf buf(*std::cout.rdbuf()); std::ostream ucout(&buf); ucout << "Hello, world!" << std::endl; // prints "HELLO, WORLD!" ``` What I want to achieve is the more-or-less the inverse, I want to read from a stream and have all input converted to lowercase. I have the following: ``` class lower_streambuf : public std::streambuf { public: lower_streambuf(std::streambuf &real) : m_realBuffer(real) { } protected: virtual int underflow() { return std::tolower(m_realBuffer.sbumpc()); } private: std::streambuf &m_realBuffer; }; ``` However, when I try and use this one like this: ``` lower_streambuf buf(*std::cin.rdbuf()); std::istream lcin(&buf); std::string line; std::getline(lcin, line); ``` The result is a segmentation fault. Am I overriding or calling the wrong functions? Please note I am somewhat of a novice in C++. Please also note that I understand I can read the input completely and simply convert it to lowercase once it has been read, but this is more for learning/academic purposes rather than anything practical.

Original source