<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Mein eigenes Streamobjekt?]]></title><description><![CDATA[<p>Was muss ich tun um ein eigenen Streamobjekt zu basteln? Also sowas wie cout, nur dass ich da entscheiden will wo der Stream hingeht, also in eine Datei, oder als Ausgabe auf der Konsole, oder, oder, oder.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/325472/mein-eigenes-streamobjekt</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Jul 2026 18:15:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/325472.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 04 May 2014 14:54:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 14:54:31 GMT]]></title><description><![CDATA[<p>Was muss ich tun um ein eigenen Streamobjekt zu basteln? Also sowas wie cout, nur dass ich da entscheiden will wo der Stream hingeht, also in eine Datei, oder als Ausgabe auf der Konsole, oder, oder, oder.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397328</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397328</guid><dc:creator><![CDATA[StreamSteam]]></dc:creator><pubDate>Sun, 04 May 2014 14:54:31 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 15:01:33 GMT]]></title><description><![CDATA[<p>Wenn du nur den Stream umleiten willst, kannst du den internen Streambuffer umbiegen. Schau dir mal <code>std::ostream::rdbuf()</code> an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397331</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 04 May 2014 15:01:33 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 15:18:16 GMT]]></title><description><![CDATA[<blockquote>
<p>Also sowas wie cout, nur dass ich da entscheiden will wo der Stream hingeht, also in eine Datei, oder als Ausgabe auf der Konsole, oder, oder, oder.</p>
</blockquote>
<p>Also etwa in der Richtung?</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;ostream&gt;

class MyStreambuf : public std::streambuf
{
public:

	virtual int_type overflow( int_type ch = traits_type::eof() )
	{
		if( !traits_type::eq_int_type(ch, traits_type::eof()) )
			return std::cout.rdbuf()-&gt;sputc( traits_type::to_char_type(ch) );

		return traits_type::eof();
	}
};

int main()
{
	MyStreambuf buf;
	std::ostream stream(&amp;buf);

	stream &lt;&lt; &quot;Hallo!\n&quot;;
}
</code></pre>
<p>Hier wird jedes Zeichen an <code>cout</code> weitergegeben. Kann man aber auch mit einem unterliegenden<a href="http://en.cppreference.com/w/cpp/io/basic_filebuf" rel="nofollow"> <code>std::filebuf</code> </a>machen, um es in eine Datei zu lenken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397335</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 04 May 2014 15:18:16 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 15:49:27 GMT]]></title><description><![CDATA[<p>Ja, ich glaube umbiegen trifft es ganz gut. Ich mystream &lt;&lt; &quot;hier kommt was&quot; machen können und im Objekt selbst wird dann entschieden wohin umgeleitet wird, also Datei, die Konsole etc.</p>
<p>Arcoth, dein Code sieht ja höhst professionell aus, kannst du den etwas erklären? Ich will nicht einfach was benutzen, sondern auch verstehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397339</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397339</guid><dc:creator><![CDATA[StreamSteam]]></dc:creator><pubDate>Sun, 04 May 2014 15:49:27 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 17:26:23 GMT]]></title><description><![CDATA[<p>Es gibt in den I/O-Streams zwei Ebenen.<br />
Die eine Ebenen sind die std::istream und std::ostream Klassenhierachien. Das sind die &quot;höheren&quot; Objekte, mit denen der normale User zu tun hat. std::cout z.B. ist vom Typ std::ostream, und du kennst garantiert std::ofstream und std::ostringstream für Dateien und Strings. Die erledigen in Wirklichkeit nicht die eigentliche Ein-/Ausgabe, sondern kümmern sich nur darum, dass Zahlen in Zeichenketten umgewandelt werden (bzw. umgekehrt), dass eine Ausgabebreite eingehalten wird und dass Fehlerzustände richtig gespeichert werden; so Formatierungszeugs halt. Die eigentliche I/O erledigen die Streambuffer. Ein Streambuf hat verschiedene Lowlevel-Funktionen. Er ist z.B. nur in der Lage einzelne Zeichen bzw. Zeichenketten ein/auszugeben, die Position im Stream zu setzen o.ä, aber erledigt nicht die eigentliche Formatierung. Der grundlegende Streambuffer ist std::streambuf. Davon abgeleitet gibt es einen Streambuffer, der in Dateien schreibt/von ihnen liest, einen der in Strings schreibt/von ihnen liest und du kannst selber auch welche schreiben, die z.B. Daten über Netzwerke transferieren.<br />
Um die Arbeit für Leute, die so etwas schreiben, zu vereinfachen, ist die Funktionalität vieler Funktionen im std::streambuf schon vorgegeben. Es gibt bspw. die Funktion sputc, die ein Zeichen ausgeben soll. sputc schiebt dazu dieses Zeichen einfach in einen internen Buffer. Ist dieser interne Buffer voll, wird die virtuelle Funktion overflow aufgerufen, die diesen Buffer auf das Ausgabemedium schreiben soll. Diesen internen Buffer muss man jedoch erst setzen. Ist kein Buffer gesetzt - wie bei Arcoth - wird einfach direkt overflow aufgerufen.<br />
Der Parameter für overflow ist das Zeichen, was nicht ausgegeben werden konnte. Es ist jedoch nicht einfach vom Typ char, weil es auch vorkommen kann, dass es kein solches Zeichen gibt. In diesem Fall wird das spezielle Zeichen eof übergeben. Aus diesem Grund ist der Parameter vom Typen int_type. int_type ist in der Lage, jedes Zeichen plus eof zu speichern. Der Rückgabewert ist eof, wenn kein Zeichen ausgegeben wurde - z.B. wegen einem Fehler, bzw. wenn eof übergeben wurde, ansonsten irgendein anderes Zeichen.<br />
Was soll nun dieses traits_type? Nun, in Wirklichkeit sind all diese Klassen Templates. std::ostream ist in Wirklichkeit std::basic_ostream&lt;char&gt;. Ich weiß nicht, ob du weißt, was ein Template ist, deswegen werde ich da nicht so genau drauf eingehen. Wichtig ist nur: Es gibt verschiedene Encodings. ASCII ist ein simples Encoding, dort ist jedes Zeichen 1 Byte groß und passt somit wunderbar in ein char. Um ASCII-Strings auszugeben, muss man also mit chars arbeiten. UTF-32 hingegen ist ein Encoding, bei dem jedes Zeichen 4 Bytes groß ist. Man müsste also mit uint32_t arbeiten, anstatt mit char. Aus diesem Grund sind alle Streams konfigurierbar für den Typen, mit dem sie arbeiten. Um jetzt zu prüfen,ob in einem char 'A' drin steht, kann man einfach schreiben: character == 'A'. Es kann jedoch sein, dass es irgendein spezielles Encoding gibt, bei dem man das nicht so prüfen kann. Aus diesem Grund gibt es die Charactertraits. Die Charactertraits definieren die Operationen, die man mit diesen Typen machen kann. Z.B. gibt es dort die Funktion eq, die prüft ob ein Zeichen gleich einem anderen ist. In den Streams stände da z.B. für einen Vergleich</p>
<pre><code>if (traits_type::eq(character, other_character))
</code></pre>
<p>Genauso werden dort auch Typen definiert - wie int_type, und eof.<br />
Arcoths Code leitet nun einfach einen eigenen Streambuf von std::streambuf ab und überschreibt overflow. Ist das übergebene Zeichen nicht eof - überprüft mit der Funktion traits_type::eq_int_type, die zwei int_types miteiander vergleicht, wird es nach std::cout geschrieben. Dazu wird rdbuf aufgerufen, was einene Zeiger auf den internen Streambuffer von std::cout zurückliefert. Dort wird das schon oben erwähnte sputc aufgerufen. sputc will jedoch einen char_type, weswegen das erst mit traits_type::to_char_type konvertiert wird. Das Ergebnis davon wird einfach zurückgegeben.<br />
In der main wird lediglich ein std::ostream erstellt, der diesen Streambuffer nutzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397351</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397351</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sun, 04 May 2014 17:26:23 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 17:40:16 GMT]]></title><description><![CDATA[<blockquote>
<p>Man müsste also mit uint32_t arbeiten, anstatt mit char.</p>
</blockquote>
<p>Nicht ganz: Mit <code>wchar_t</code> oder - seit C++11 - <code>char32_t</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397352</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397352</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 04 May 2014 17:40:16 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 17:45:34 GMT]]></title><description><![CDATA[<p>Danke für die ausführliche Erklärung, das muss ich jetzt erst einmal verdauen^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397353</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397353</guid><dc:creator><![CDATA[StreamSteam]]></dc:creator><pubDate>Sun, 04 May 2014 17:45:34 GMT</pubDate></item><item><title><![CDATA[Reply to Mein eigenes Streamobjekt? on Sun, 04 May 2014 18:17:43 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Man müsste also mit uint32_t arbeiten, anstatt mit char.</p>
</blockquote>
<p>Nicht ganz: Mit <code>wchar_t</code> oder - seit C++11 - <code>char32_t</code> .</p>
</blockquote>
<p>Ah, verdammt. War am Überlegen wie das Ding hieß und zu faul nachzugucken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2397357</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2397357</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sun, 04 May 2014 18:17:43 GMT</pubDate></item></channel></rss>