none
wostream umleiten RRS feed

  • Frage

  • Hallo!

    Ich habe eine Streamklasse, welche in mehrere streambuffer schreibt.
    Funktioniert prima mit ostream, cout, usw... mit Unicode streams leider nicht.
    Kann mir da jemand auf die Sprünge helfen?

    Vielen herzlichen Dank!

    Lars

     

    template<typename T = char>
    class Basic_ComposeBuffer
    	: public std::basic_streambuf< T >
    {
    private:
    	std::vector<std::basic_streambuf< T >* >	m_Bufs;
    
    public:
    	Basic_ComposeBuffer(void)
    	{
    	}
    
    	~Basic_ComposeBuffer(void)
    	{
    	}
    
    	void addBuffer(std::basic_streambuf< T >* buf)
    	{
    		m_Bufs.push_back(buf);
    	}
    
    	virtual int overflow(int c)
    	{
    		std::for_each(m_Bufs.begin(),m_Bufs.end(),
    			std::bind2nd(std::mem_fun(&std::basic_streambuf< T >::sputc),c));
    
    		return c;
    	}
    };
    
    typedef Basic_ComposeBuffer<char> ComposeBuffer;
    typedef Basic_ComposeBuffer<wchar_t> ComposeBufferW;
    
    
    template<class stream_type = std::ostream, typename buf_type = char>
    class Basic_ComposeStream :
    	public stream_type
    {
    private:
    	Basic_ComposeBuffer<buf_type>	m_Buffer;
    
    public:
    	Basic_ComposeStream(void)
    		: stream_type(NULL)
    	{
    		stream_type::rdbuf(&m_Buffer);
    	}
    
    	~Basic_ComposeStream(void)
    	{
    	}
    
    	void linkStream(stream_type& out)
    	{
    		out.flush();
    		m_Buffer.addBuffer(out.rdbuf());
    	}
    };
    
    typedef Basic_ComposeStream<std::ostream, char> ComposeStream;
    typedef Basic_ComposeStream<std::wostream, wchar_t> ComposeStreamW;
    

    Test
    Freitag, 11. März 2011 09:20

Antworten

  • Die Typen Deiner overflow Funktion passen nicht. Die ist eben nicht immer int. Du kannst einfach int_type nehmen.

    ...
        virtual int_type overflow(int_type c)
    ...

    Du hast in der Unicode Version keine Funktion überschrieben sondern eine neue Funktion erzeugt.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • Als Antwort markiert Lamizi Freitag, 11. März 2011 13:45
    Freitag, 11. März 2011 13:42
    Moderator

Alle Antworten

  • Und was ist jetzt Dein Problem?

    Dein Code compiliert korrekt unter VS-2010 SP1 und auch instanziieren lassen sich die Klassen.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Freitag, 11. März 2011 09:51
    Moderator
  • Hallo Martin,

    hast natürlich recht. Man sollte schon noch ein Problem benennen.
    Auch bei mir compiliert VS2003 alles korrekt. Funktion lässt sich auch ausführen.
    ASCII funktioniert super aber bei Unicode wird nichts in den Stream geschrieben.

    Hier mal die Funktion:

    	// Multibyte
    	ofstream file("coutlog.txt");
    	ComposeStream	FullStream;
    	{
    		FullStream.linkStream(file);
    		FullStream.linkStream(cout);
    		FullStream << "Hallo Ansi Welt" << endl;
    
    		IOSwitch coutswitch(cout, FullStream.rdbuf()); 
    		cout << "Jetzt geht alles auf cout auch in die Datei 'coutlog.txt' " << endl; 
    		cout << "Jede Zahl: " << 1./7 << endl; 
    		cout << " .. und jedes Zeichen: " << '#' << endl; 
    	}
    
    	cout << "und jetzt ist alles wie vorher" << endl; 
    	file << "--- Ende --- " << endl; 
    	file.close();
    
    	//Unicode
    	wofstream filew("coutlogw.txt");
    	ComposeStreamW	FullStreamW;
    	{
    		FullStreamW.linkStream(filew);
    		FullStreamW.linkStream(wcout);
    		FullStreamW << L"Hallo Unicode Welt" << endl;
    
    		IOSwitchW wcoutswitch(wcout, FullStreamW.rdbuf()); 
    		wcout << L"Jetzt geht alles auf wcout auch in die Datei 'coutlogw.txt' " << endl; 
    		wcout << L"Jede Zahl: " << 1./7 << endl; 
    		wcout << L" .. und jedes Zeichen: " << '#' << endl; 
    	}
    	wcout << L"und jetzt ist alles wie vorher" << endl; 
    	filew << L"--- Ende --- " << endl; 
    	filew.close();
    

    Test
    Freitag, 11. März 2011 09:54
  • >         IOSwitch coutswitch(cout, FullStream.rdbuf());

    Was ist IOSwitch?

    Tipp: Bau immer ein komplettes Mini-Sample. Das erleichtert es den Testern... :-P


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Freitag, 11. März 2011 11:26
    Moderator
  • Hier noch der IOSwitch. Die Ausgabe funktioniert aber auch hier
    FullStreamW << L"Hallo Unicode Welt" << endl;
    schon nicht.

    template<typename T = char, class buf_type = std::streambuf>
    class Basic_IOSwitch
    { 
    private: 
    	std::basic_ios< T >*	m_IOS; 
    	buf_type*				m_OriginBuffer; 
    
    	// --- nicht kopierbar 
    	Basic_IOSwitch(const Basic_IOSwitch&); 
    	Basic_IOSwitch& operator=(const Basic_IOSwitch&); 
    
    public: 
    	Basic_IOSwitch(std::basic_ios< T >& ios, buf_type* sb)
    		: m_IOS(&ios) 
    		, m_OriginBuffer(ios.rdbuf(sb))
    	{
    	}
    
    	~Basic_IOSwitch()
    	{
    		if(m_IOS) 
    			m_IOS->rdbuf(m_OriginBuffer);
    	}
    
    	buf_type* rdbuf() const {return m_OriginBuffer;}
    };
    
    typedef Basic_IOSwitch<char, std::streambuf> IOSwitch;
    typedef Basic_IOSwitch<wchar_t, std::wstreambuf> IOSwitchW;
    
    DANKE!!!
    Freitag, 11. März 2011 11:43
  • Ui, ging mir genau so. Klingt lustig, aber: wstreams können von sich aus keine wchar_ts verarbeiten. Afaik musst du erst irgendein Locale setzen, das aber in Windows-Umgebungen nicht existiert. wchar_t ist sowieso einer der größten Fehler des Standardkommitees; lass besser die Finger davon und steig auf UTF-8 bzw. UTF-16 um (es gibt sehr gute Drittbibliotheken, die dir das erleichtern, z.B. UTF8-CPP).

    Gruß, Ky

    Freitag, 11. März 2011 13:37
  • Die Typen Deiner overflow Funktion passen nicht. Die ist eben nicht immer int. Du kannst einfach int_type nehmen.

    ...
        virtual int_type overflow(int_type c)
    ...

    Du hast in der Unicode Version keine Funktion überschrieben sondern eine neue Funktion erzeugt.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • Als Antwort markiert Lamizi Freitag, 11. März 2011 13:45
    Freitag, 11. März 2011 13:42
    Moderator
  • Super! Vielen Dank für die wieder einmal tolle Unterstützung hier im Forum!

    Gruß Lars

    Freitag, 11. März 2011 13:46