<?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[cout umleiten]]></title><description><![CDATA[<p>Ich hab eine externe Funktion Rprintf(), die genauso funktioniert, wie das printf() aus C. Alles was über cout ausgegeben wird, soll nicht auf die Standardausgabe, sondern nach Pprintf().</p>
<p>Wie macht man das, ohne eine eigene große ostream-Klasse zu schreiben?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/310171/cout-umleiten</link><generator>RSS for Node</generator><lastBuildDate>Tue, 04 Aug 2026 23:26:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/310171.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 05 Nov 2012 13:18:22 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 13:18:22 GMT]]></title><description><![CDATA[<p>Ich hab eine externe Funktion Rprintf(), die genauso funktioniert, wie das printf() aus C. Alles was über cout ausgegeben wird, soll nicht auf die Standardausgabe, sondern nach Pprintf().</p>
<p>Wie macht man das, ohne eine eigene große ostream-Klasse zu schreiben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267651</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267651</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Mon, 05 Nov 2012 13:18:22 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 13:28:15 GMT]]></title><description><![CDATA[<p>Du meinst, du willst nicht bloß das, was über cout ausgegeben würde, zeichenweise an dein rprintf leiten, sondern du möchtest auch die ganze Formatierung (z.B. wie ein int ausgegeben wird) von rprintf machen lassen? In dem Fall wäre wohl dies</p>
<blockquote>
<p>eine eigene große ostream-Klasse</p>
</blockquote>
<p>die vermeintlich kürzeste und direkteste Lösung. Ich dachte zwar zu erst an die locale-facets, aber damit kommst du nicht an solche Sachen wie</p>
<pre><code class="language-cpp">ostream&amp; ostream::operator&lt;&lt; (const void* val);
</code></pre>
<p>oder</p>
<pre><code class="language-cpp">ostream&amp; ostream::write ( const char* s , streamsize n );
</code></pre>
<p>. Schließlich musst du sämtliche Operationen überschreiben, wenn die Umleitung der Formatierung vollständig sein soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267659</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267659</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 05 Nov 2012 13:28:15 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 13:34:12 GMT]]></title><description><![CDATA[<p>Du leitest ( <code>public</code> ) von <code>streambuf</code> ab und überlädst <code>xsputn</code> . Anschließend übergibst du <code>cout</code> per <code>rdbuf</code> eine Instanz dieses Streambufs.</p>
<p>Edit: Ah, SeppJ, ich dachte er will nur <em>die Ausgabe</em> umleiten...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267662</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267662</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Mon, 05 Nov 2012 13:34:12 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 13:38:54 GMT]]></title><description><![CDATA[<p>Obwohl, eigentlich will er doch meines:</p>
<blockquote>
<p>Alles was über <strong>cout ausgegeben wird</strong>, soll nicht auf die <em>Standardausgabe</em>, sondern nach <em>Pprintf()</em>.</p>
</blockquote>
<p>Also er will nur die Ausgabe umleiten. &gt;:D</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267669</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267669</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Mon, 05 Nov 2012 13:38:54 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 14:42:55 GMT]]></title><description><![CDATA[<p>Sone schrieb:</p>
<blockquote>
<p>Du leitest ( <code>public</code> ) von <code>streambuf</code> ab und überlädst <code>xsputn</code> . Anschließend übergibst du <code>cout</code> per <code>rdbuf</code> eine Instanz dieses Streambufs.</p>
</blockquote>
<p>Hallo Sone,</p>
<p>Du antwortest auf viele Fragen sehr schnell, und oft entweder unvollständig oder falsch. Tue uns doch den Gefallen, und überprüfe Deine Antwort, indem Du es z.B. vorher selbst ausprobierst oder noch mal genau nachliest.<br />
Das hätte dann drei Vorteile:<br />
1.) Der Fragende bekommt die richtige Antwort, oder zumindest keine falsche, was schlimmer ist als keine Antwort<br />
2.) andere Leute müssen Deine Antworten nicht genervt korrigieren<br />
3.) Du lernst selber eine Menge dazu</p>
<p>Hallo Ramanujan,</p>
<p>Ja, das Umleiten der Ausgabe von cout ist unter C++ leicht möglich. Zunächst benötigst Du einen eigenen <a href="http://www.cplusplus.com/reference/iostream/streambuf/" rel="nofollow">streambuf</a>, der nach Pprintf schreibt:</p>
<pre><code class="language-cpp">#include &lt;streambuf&gt;

class To_Pprintf : public std::streambuf
{
protected:
    virtual int_type overflow( traits_type::int_type m = traits_type::eof() )
    {
        if( !traits_type::eq_int_type( m, traits_type::eof() ) )
            Pprintf( &quot;%c&quot;, traits_type::to_char_type( m ) ); // genau ein Zeichen auf Pprintf ausgeben
        return traits_type::not_eof( m ); // Ok
    }
};
</code></pre>
<p>anschließend musst Du in Deiner main-Funktion cout auf eben diesen streambuf umleiten:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

// To_Pprintf (s.o.)

int main()
{
    using namespace std;
    To_Pprintf sb_Pprintf;
    streambuf* oldSb = cout.rdbuf( &amp;sb_Pprintf );

    // .. Dein Programmcode; wie bisher
    //       alle Ausgaben auf cout gehen jetzt nach Pprintf

    cout.rdbuf( oldSb ); // alten Zustand wieder herstellen
    return 0;
}
</code></pre>
<p>Das mit dem Umschalten von cout geht auch noch etwas eleganter. Schaue Dir dazu in diesem <a href="http://www.c-plusplus.net/forum/p942394#942394" rel="nofollow">Beitrag die Klasse IoSwitch</a> an.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267704</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267704</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 05 Nov 2012 14:42:55 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 15:13:58 GMT]]></title><description><![CDATA[<p>Werner Salomon schrieb:</p>
<blockquote>
<p>Sone schrieb:</p>
<blockquote>
<p>Du leitest ( <code>public</code> ) von <code>streambuf</code> ab und überlädst <code>xsputn</code> . Anschließend übergibst du <code>cout</code> per <code>rdbuf</code> eine Instanz dieses Streambufs.</p>
</blockquote>
<p>Hallo Sone,</p>
<p>Du antwortest auf viele Fragen sehr schnell, und oft entweder unvollständig oder falsch. Tue uns doch den Gefallen, und überprüfe Deine Antwort, indem Du es z.B. vorher selbst ausprobierst oder noch mal genau nachliest.</p>
</blockquote>
<p>Ich verstehe deinen Einwand hier nicht, Werner. Sones Variante funktioniert doch:</p>
<pre><code class="language-cpp">#include &lt;streambuf&gt;
#include &lt;fstream&gt;
#include &lt;iostream&gt;

std::ofstream test_stream(&quot;text.txt&quot;);

class To_Pprintf : public std::streambuf
{
protected:
    virtual std::streamsize xsputn(const char * s, std::streamsize n)
    {
        test_stream.write(s, n);//Zu Testzwecken
        return n;
    }
};

int main()
{
    To_Pprintf sb_Pprintf;
    auto old = std::cout.rdbuf( &amp;sb_Pprintf );

    std::cout &lt;&lt; &quot;Hallo Welt!&quot; &lt;&lt; 02;
    std::cout.rdbuf(old);
}
</code></pre>
<p>Es wird nichts ausgegeben und in der Datei steht wie erwartet &quot;Hallo Welt!02&quot;...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267720</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267720</guid><dc:creator><![CDATA[heuschrecker]]></dc:creator><pubDate>Mon, 05 Nov 2012 15:13:58 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 15:27:44 GMT]]></title><description><![CDATA[<p>heuschrecker schrieb:</p>
<blockquote>
<p>Es wird nichts ausgegeben und in der Datei steht wie erwartet &quot;Hallo Welt!02&quot;...</p>
</blockquote>
<p>Hallo heuschrecker,</p>
<p>bist Du sicher, dass dort &quot;Hallo Welt!02&quot; steht und nicht &quot;Hallo Welt!&quot;? Schau noch mal genau hin. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
.. und gebe anschließend noch ein paar Zahlen und dann wieder einen Text aus.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267729</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267729</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 05 Nov 2012 15:27:44 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 15:51:14 GMT]]></title><description><![CDATA[<p>Das mit xsputn funktioniert bei mir auch. Nur wird aus 02 logischerweise 2, denn ne führende Null ist meines Wissens doch für Oktalzahlen reserviert, also steht bei mir in der text.txt &quot;Hallo Welt!2&quot;</p>
<p>Edit: Das ändert aber natürlich gar nichts an den Dingen, die Salomon in Bezug auf Sone's Antworten gesagt hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267734</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267734</guid><dc:creator><![CDATA[Incocnito]]></dc:creator><pubDate>Mon, 05 Nov 2012 15:51:14 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 15:53:30 GMT]]></title><description><![CDATA[<p>Incocnito schrieb:</p>
<blockquote>
<p>Das mit xsputn funktioniert bei mir auch. Nur wird aus 02 logischerweise 2, denn ne führende Null ist meines Wissens doch für Oktalzahlen reserviert, also steht bei mir in der text.txt &quot;Hallo Welt!2&quot;</p>
</blockquote>
<p>Oh ja, tut mir Leid! In meiner Datei steht &quot;Hallo Welt!2&quot; ^^</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/7393">@Werner</a>: Damit dürfte sich deine Frage beantworten.<br />
Hier noch ein Beispiel:<br />
Statt Z. 22 in meinem Beispiel</p>
<pre><code class="language-cpp">std::cout &lt;&lt; &quot;Hallo Welt!&quot; &lt;&lt; 2 &lt;&lt; ' ' &lt;&lt; 1.84 &lt;&lt; &quot; Blah&quot;;
</code></pre>
<p>Ausgabe:</p>
<blockquote>
<p>Hallo Welt!2 1.84 Blah</p>
</blockquote>
<p>Also was ist da falsch/schlecht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267740</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267740</guid><dc:creator><![CDATA[heuschrecker]]></dc:creator><pubDate>Mon, 05 Nov 2012 15:53:30 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 19:48:31 GMT]]></title><description><![CDATA[<p>Danke für die vielen Lösungsvorschläge.<br />
Der Vorschlag von Sone/heuschrecker funktioniert gut und zudem ist er auch noch schön kurz (vom Code her).</p>
<p>Zwei Fragen hab ich aber noch:<br />
1.) In der xsputn hab ich jetzt folgenden Code stehen. Kann man da eleganter \0 ans Ende des Strings schreiben?</p>
<pre><code>virtual std::streamsize xsputn(const char * s, std::streamsize n) {
    	 std::vector&lt;char&gt; t(n+1);
    	 for (int i = 0; i &lt; n; i++)
    		 t[i] = s[i];
    	 t[n] = '\0';
         Rprintf(&amp;t[0]);
         return n;
     }
</code></pre>
<p>2.) Warum fügt std::endl keine neue Zeile ein?<br />
Edit: Es ist sogar noch schlimmer: Wenn man einmal std::endl verwendet, kommt gar keine Ausgabe mehr.</p>
<p>Edit^2:<br />
Mit Werners Lösung tritt der endl-Bug nicht auf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267839</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267839</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Mon, 05 Nov 2012 19:48:31 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 19:37:03 GMT]]></title><description><![CDATA[<pre><code>virtual std::streamsize xsputn(const char * s, std::streamsize n) 
{  
         Rprintf( (std::string(s, n) + '\n').c_str() ); 
         return n; 
}
</code></pre>
<p>(Ungetestet)</p>
<p>Und zu der Frage, wieso <code>endl</code> keine Zeile hinzufügt: <code>endl</code> sollte eigentlich ein newline in den Stream schreiben und flushen. Versuch mal, ganz normal '\n' auszugeben. Wenn das nicht geht, dann liegt das wohl entweder an Rprintf oder meine Version ist einfach falsch (wahrscheinlicher <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> ).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267848</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267848</guid><dc:creator><![CDATA[sone_logoff]]></dc:creator><pubDate>Mon, 05 Nov 2012 19:37:03 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 19:50:40 GMT]]></title><description><![CDATA[<p>Mit Werners Lösung (overflow() überschreiben) tritt der endl-Bug nicht auf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267858</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267858</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Mon, 05 Nov 2012 19:50:40 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 19:59:31 GMT]]></title><description><![CDATA[<p>sone_logoff schrieb:</p>
<blockquote>
<p>oder meine Version ist einfach falsch (wahrscheinlicher <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> ).</p>
</blockquote>
<p>No shit, Sherlock!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267864</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267864</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 05 Nov 2012 19:59:31 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 21:08:54 GMT]]></title><description><![CDATA[<p>heuschrecker schrieb:</p>
<blockquote>
<p>Also was ist da falsch/schlecht?</p>
</blockquote>
<p>Hallo heuschrecker, hallo Incocnito,</p>
<p>falsch/schlecht daran ist, dass das nur zufällig bei Euch funktioniert und auch nicht zu 100% wie schon einige Postings inzwischen zeigen. Es funktioniert bei Verwendung einer Dinkumware-C++-Lib definitiv nicht. Sobald z.B. ein einzelnes Zeichen oder eine Zahl ausgegben werden, geht der Stream in den Fehlerzustand und dann kommt gar nichts mehr raus. Der C++-Standard garantiert auch nicht, dass das so geht.</p>
<p>Ein <a href="http://www.cplusplus.com/reference/iostream/streambuf/" rel="nofollow">std::streambuf</a> hat nur zwei public Methoden mit denen man Zeichen schreiben kann. Das sind <a href="http://www.cplusplus.com/reference/iostream/streambuf/sputc/" rel="nofollow">sputc()</a> und <a href="http://www.cplusplus.com/reference/iostream/streambuf/sputn/" rel="nofollow">sputn()</a>. Letztere ruft direkt xsputn, wird aber nur aufgerufen, wenn auch N Bytes direkt zur Verfügung stehen. Das ist i.a. nur bei der Ausgabe von Strings/char-Arrays der Fall.</p>
<p>Lt. Standard soll <code>sputc</code> folgendes machen:</p>
<p>C++ Standard schrieb:</p>
<blockquote>
<p><strong>int_type sputc(char_type c);</strong><br />
<em>Returns</em>: If the output sequence write position is not available, returns <code>overflow(traits::to_int_type(c))</code> . Otherwise, stores c at the next pointer for the output sequence, increments the pointer,<br />
and returns <code>traits::to_int_type(c)</code> .</p>
</blockquote>
<p>Also wäre das im Sinne des Standards:</p>
<pre><code>std::streambuf::int_type std::streambuf::sputc( std::streambuf::char_type c )
{
    if( !pptr() || pptr() &gt;= epptr() ) // If the output sequence write position is not available ...
        return overflow( traits_type::to_int_type( c ) ); // returns overflow(traits::to_int_type(c))

    *pptr() = c; // Otherwise, stores c at the next pointer for the output sequence,
    pbump( 1 ); // increments the pointer,
    return traits_type::to_int_type( c ); // and returns traits::to_int_type(c)
}
</code></pre>
<p>Bei heuschrecker und Incocnito sieht das <code>sputc</code> wahrscheinlich so aus (so vermute ich):</p>
<pre><code>std::streambuf::int_type std::streambuf::sputc( std::streambuf::char_type c )
{
    return xsputn( &amp;c, 1 ) == 1? traits_type::to_int_type( c ): traits_type::eof();
}
</code></pre>
<p>das ist nicht verboten, denn xsputn tut im Grunde dann das, was der Standard vorschreibt. Es ist vielleicht etwas unperformant, weil ja in xputn eine for-Schleife betreten und verlassen werden muss, obwohl beim Aufruf schon klar ist, dass nur 1 Zeichen ausgegeben werden soll. Welche Umgebung bzw. C++-Lib benutzt Ihr?</p>
<p>Wie auch immer, der Zweck von <code>xsputn</code> ist</p>
<p>C++ Standard schrieb:</p>
<blockquote>
<p>Classes derived from basic_streambuf can provide more efficient ways to implement xsgetn() and xsputn() by overriding these definitions from the base class.</p>
</blockquote>
<p>Andererseits enden alle put-Wege bei <code>overflow</code> . Das was in <a href="http://www.cplusplus.com/reference/iostream/streambuf/overflow/" rel="nofollow">overflow</a> mit dem Zeichen geschieht ist spezifisch, nur von der abgeleiteten Klasse abhängig.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267908</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267908</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 05 Nov 2012 21:08:54 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 21:30:51 GMT]]></title><description><![CDATA[<p>Ich benutz' Windows 7 64 bit, GCC 4.7.2.<br />
sputc sieht bei mir so aus:</p>
<pre><code>namespace std
{
    template&lt;typename _CharT, typename _Traits&gt;
    class basic_streambuf
    {
    public:
        int_type
        sputc(char_type __c)
        {
            int_type __ret;
            if (__builtin_expect(this-&gt;pptr() &lt; this-&gt;epptr(), true))
            {
                *this-&gt;pptr() = __c;
                this-&gt;pbump(1);
                __ret = traits_type::to_int_type(__c);
            }
            else
                __ret = this-&gt;overflow(traits_type::to_int_type(__c));
            return __ret;
        }
    };
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2267919</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267919</guid><dc:creator><![CDATA[Incocnito]]></dc:creator><pubDate>Mon, 05 Nov 2012 21:30:51 GMT</pubDate></item><item><title><![CDATA[Reply to cout umleiten on Mon, 05 Nov 2012 21:45:55 GMT]]></title><description><![CDATA[<p>Incocnito schrieb:</p>
<blockquote>
<p>Ich benutz' Windows 7 64 bit, GCC 4.7.2.<br />
sputc sieht bei mir so aus:</p>
</blockquote>
<p>dann wundert mich das aber stark, dass der streambuf bei Ausgabe einer Zahl in xsputn landet.</p>
<p>Kannst Du das debuggen?</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2267922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2267922</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 05 Nov 2012 21:45:55 GMT</pubDate></item></channel></rss>