3

cout(または別のostream)に渡されるすべての文字列をrot13したいとします。これにより、たとえばcout<<"Foo Bar Baz.;"(またはcout<<rot13<<"Foo Bar Baz.";)出力が出力されます。Sbb One Onm.

どうすればいいですか?

(私の最初のアイデアは、coutのstreambufを、すべての作業を行うstreambufから派生したクラスに置き換えることでした。しかし、元のstreambufがコンソールにデータを転送する責任があると見なすと、まったく機能しませんでした。)

4

2 に答える 2

3

char *、std ::stringなどのoperator<<をオーバーロードし、変換されたテキストを出力する独自のストリームを作成できます。

#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;
}
于 2013-01-29T13:29:01.137 に答える
1

coutのstreambufを自分でラップして、ラップされたバッファーにすべての呼び出しを転送できませんでしたか?
「put」呼び出しをラップされたstreambufに転送する前に、いくつかのエンコードを行う必要があるだけです。

とはいえ、少しのrot13には大変な作業です。

于 2013-01-29T13:14:42.250 に答える