如何修改传递给cout的字符串?

时间:2013-01-29 12:40:17

标签: c++ iostream

假设我想将每个传递给cout(或另一个ostream)的字符串变为rot13,那么,说cout<<"Foo Bar Baz.;"(或甚至cout<<rot13<<"Foo Bar Baz.";)输出Sbb One Onm.

我将如何做到这一点?

(我的第一个想法是用一个可以完成所有工作的streambuf派生类取代cout的streambuf。但是看到原来的streambuf负责将东西引导到控制台......这根本没有用到。)

2 个答案:

答案 0 :(得分:3)

您可以编写自己的流,重载运算符&lt;&lt;对于char *,std :: string等,并打印转换后的文本。

#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;
    }
};

下一步是声明这种类型的全局变量,然后声明用新变量替换cout的宏。

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

#define cout cout_rot13

然后cout的所有实例都将成为cout_rot13。

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

    return 0;
}

答案 1 :(得分:1)

难道你不能将cout的streambuf包装在你自己的中,转发所有对包装缓冲区的调用吗? 在将“put”调用转发到包装的streambuf之前,您只需要进行一些编码。

但是,对于一点点腐烂来说,这是很多工作。