How can I change the lines passed to cout?

Suppose I want rot13 each line to be passed to cout (or another ostream), so let's say cout<<"Foo Bar Baz.;"

(or even cout<<rot13<<"Foo Bar Baz.";

) outputsSbb One Onm.

How can i do this?

(My first idea was to replace cout streambuf with a streambuf based class that will do all the work. But since the original streambuf is responsible for managing things on the console ... that didn't work at all.)

+3


source to share


2 answers


You can write your own stream that overloads the <<operator for char *, std :: string, and others and prints out the converted text.

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;

class ostream_rot13 : public basic_ostream <char, char_traits<char> >
{
public:
    ostream_rot13(std::basic_streambuf<char, char_traits<char> >* sb) 
    : basic_ostream<char, char_traits<char> >(sb) {}

    ostream_rot13& operator<<(const char* text)
    {
        std::string s(text);

        int rot=13;
        std::transform(std::begin(s), std::end(s), ostream_iterator<char>(*this), [rot] (char c) { 
            if(c >= 'a' && c <= 'z')
                return 'a' + (c + rot - 'a') % 26;
            else if(c >= 'A' && c <= 'Z')
                return 'A' + (c + rot - 'A') % 26;

            return (int)c;
        });

        return *this;
    }
};

      

The next step is to declare a global variable of this type, and then a macro that replaces cout with a new variable.



ostream_rot13 cout_rot13(std::cout.rdbuf());

#define cout cout_rot13

      

And then all instances of cout will become cout_rot13.

int main() 
{
    cout << "Foo Bar Baz";

    return 0;
}

      

+3


source


Could you wrap the cout streambuf yourself, forwarding all calls to a packed buffer?
You just need to do some encoding before forwarding the "put" calls to the wrapped streambuf.



That's a lot of work for a small amount of rot13.

+1


source







All Articles