<?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[Logging mit ostream]]></title><description><![CDATA[<p>Moin moin,</p>
<p>in unserer Software gibt es eine C-Funktion <code>Log(fmtStr, ...)</code> , die bei jedem Aufruf eine Zeile in eine Datei schreibt.<br />
Ich möchte jetzt einen C++-Stream haben, der diese Funktion aufruft. Dazu habe ich mir den Code von <a href="https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/5zP90fSOVgU" rel="nofollow">https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/5zP90fSOVgU</a> angesehen und eine streambuf-Klasse gebaut, die Log() aufruft.</p>
<p>Damit kann ich nun</p>
<pre><code class="language-cpp">TollesLog &lt;&lt; &quot;Bla &quot; &lt;&lt; &quot;Blubb&quot;;
</code></pre>
<p>schreiben, und die Ausgabe erscheint im Logfile. Aber das Buffering stört - es muss unbedingt nach jeder Ausgabe geflusht werden. Ich bin schon auf</p>
<pre><code class="language-cpp">setf(std::ios::unitbuf);
</code></pre>
<p>gestoßen, was aber nicht das gewünschte Ergebnis bringt: es wird nun für jedes Datum Log() aufgerufen, statt &quot;zeilenweise&quot;.</p>
<p>Ich will keine newlines oder std::endl oder ähnliches in den Stream schreiben müssen. Ich möchte, dass die Programmzeile</p>
<pre><code class="language-cpp">TollesLog &lt;&lt; &quot;Bla &quot; &lt;&lt; &quot;Blubb&quot;;
</code></pre>
<p>zu einem einzigen Aufruf von Log() führt, und somit zu einer einzelnen Zeile im Logfile.</p>
<p>Wie lässt sich das bewerkstelligen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/320893/logging-mit-ostream</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Jul 2026 14:06:59 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/320893.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 16 Oct 2013 09:42:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:42:34 GMT]]></title><description><![CDATA[<p>Moin moin,</p>
<p>in unserer Software gibt es eine C-Funktion <code>Log(fmtStr, ...)</code> , die bei jedem Aufruf eine Zeile in eine Datei schreibt.<br />
Ich möchte jetzt einen C++-Stream haben, der diese Funktion aufruft. Dazu habe ich mir den Code von <a href="https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/5zP90fSOVgU" rel="nofollow">https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/5zP90fSOVgU</a> angesehen und eine streambuf-Klasse gebaut, die Log() aufruft.</p>
<p>Damit kann ich nun</p>
<pre><code class="language-cpp">TollesLog &lt;&lt; &quot;Bla &quot; &lt;&lt; &quot;Blubb&quot;;
</code></pre>
<p>schreiben, und die Ausgabe erscheint im Logfile. Aber das Buffering stört - es muss unbedingt nach jeder Ausgabe geflusht werden. Ich bin schon auf</p>
<pre><code class="language-cpp">setf(std::ios::unitbuf);
</code></pre>
<p>gestoßen, was aber nicht das gewünschte Ergebnis bringt: es wird nun für jedes Datum Log() aufgerufen, statt &quot;zeilenweise&quot;.</p>
<p>Ich will keine newlines oder std::endl oder ähnliches in den Stream schreiben müssen. Ich möchte, dass die Programmzeile</p>
<pre><code class="language-cpp">TollesLog &lt;&lt; &quot;Bla &quot; &lt;&lt; &quot;Blubb&quot;;
</code></pre>
<p>zu einem einzigen Aufruf von Log() führt, und somit zu einer einzelnen Zeile im Logfile.</p>
<p>Wie lässt sich das bewerkstelligen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360652</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360652</guid><dc:creator><![CDATA[raute]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:42:34 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:45:18 GMT]]></title><description><![CDATA[<p>mach einfach ein std::endl am ende jeder zeile, dann sind beide probleme mit einer klappe geschlagen.</p>
<p>du kannst nicht unterscheiden zwischen</p>
<pre><code>str &lt;&lt; 1 &lt;&lt; 2;
</code></pre>
<p>und</p>
<pre><code>str &lt;&lt; 1;
str &lt;&lt; 2;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2360653</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360653</guid><dc:creator><![CDATA[not smart]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:45:18 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:48:06 GMT]]></title><description><![CDATA[<p>not smart schrieb:</p>
<blockquote>
<p>mach einfach ein std::endl am ende jeder zeile</p>
</blockquote>
<p>Ja, das ist schon klar. Will ich aber nicht. Gibt es keine andere Möglichkeit?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360655</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360655</guid><dc:creator><![CDATA[raute]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:48:06 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:52:38 GMT]]></title><description><![CDATA[<p>raute schrieb:</p>
<blockquote>
<p>not smart schrieb:</p>
<blockquote>
<p>mach einfach ein std::endl am ende jeder zeile</p>
</blockquote>
<p>Ja, das ist schon klar. Will ich aber nicht. Gibt es keine andere Möglichkeit?</p>
</blockquote>
<p>Du kannst auch <code>std::flush</code> reinschieben, das ist dasselbe, nur ohne Zeilenumbruch.</p>
<p>not smart hat bereits erwähnt, dass es hier keinen semantischen Unterschied zwischen</p>
<pre><code>stream &lt;&lt; a &lt;&lt; b;
// und
stream &lt;&lt; a; stream &lt;&lt; b;
</code></pre>
<p>gibt, den dein Streambuffer feststellen könnte. Du musst dir einen Kompromiss überlegen.</p>
<p>Edit:</p>
<blockquote>
<p>Aber das Buffering stört - es muss unbedingt nach jeder Ausgabe geflusht werden.</p>
</blockquote>
<p>Wie wäre es mit einem kleineren Buffer?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360656</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360656</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:52:38 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:55:15 GMT]]></title><description><![CDATA[<p>not smart schrieb:</p>
<blockquote>
<p>du kannst nicht unterscheiden zwischen</p>
<pre><code>str &lt;&lt; 1 &lt;&lt; 2;
</code></pre>
<p>und</p>
<pre><code>str &lt;&lt; 1;
str &lt;&lt; 2;
</code></pre>
</blockquote>
<p>So ähnlich kriegt mans aber hin.</p>
<pre><code>struct HilfsLog{
    stringstream s;
    HilfsLog(Log &amp;l) : log(l){}
    HilfsLog &amp;operator &lt;&lt;(char *t){
        s &lt;&lt; t;
        return *this;
    }
    ~HilfsLog(){
        log.log(s.str().c_str());
    }
    Log &amp;log;
};
struct Log{
    HilfsLog operator (){
        return HilfsLog(this);
    }
    void log(char *s){
        Log(s, ...); //c-Funktion, nicht stuct typ
    }
} TollesLog;

//Benutzung
TollesLog() &lt;&lt; &quot;Bla&quot; &lt;&lt; &quot;Keks&quot;; //&lt;-Beim Semikolon wird das temporäre
//HilfsLog-Objekt, dass durch TollesLog() erzeugt wurde zerstört und
//ruft Log::log mit &quot;BlaKeks&quot; auf. Danach noch flushen
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2360658</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360658</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:55:15 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 09:56:34 GMT]]></title><description><![CDATA[<p>std::flush ist schon besser, aber immer noch hässlich. Völlig inakzeptabel, da lasse ich es lieber wie es ist.<br />
Was bringt es denn, die Buffergröße zu ändern? Ich will weder, dass Zeilen umbrochen werden, noch dass zwei logische Zeilen in einer physischen landen. Beides darf nicht passieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360659</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360659</guid><dc:creator><![CDATA[raute]]></dc:creator><pubDate>Wed, 16 Oct 2013 09:56:34 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:00:04 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13875">@nwp</a>: Das sieht ganz gut aus. Interessante Idee.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360661</guid><dc:creator><![CDATA[raute]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:00:04 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:04:10 GMT]]></title><description><![CDATA[<blockquote>
<p>Was bringt es denn, die Buffergröße zu ändern?</p>
</blockquote>
<p>Nun, es wird lediglich öfter geflusht, da der Buffer schneller voll ist. Ist aber wahrscheinlich nicht was du willst.</p>
<p>raute schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13875">@nwp</a>: Das sieht ganz gut aus. Interessante Idee.</p>
</blockquote>
<p>Aber was bringt das? Ich verstehe immer noch nicht, wieso du nicht einfach immer wenn geflusht werden soll das auch explizit sagst. Ist das so umständlich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360663</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360663</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:04:10 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:10:57 GMT]]></title><description><![CDATA[<p>hihi wenn wir schon beim basteln sind:</p>
<pre><code>#include &lt;iostream&gt;
struct LogHelper
{
	std::ostream&amp; Target;
	LogHelper(std::ostream&amp; Target)
		: Target(Target)
	{
	}
	~LogHelper()
	{
		Target &lt;&lt; std::endl;
	}
};
template&lt;class T&gt;
std::ostream&amp; operator&lt;&lt; (LogHelper Stream, T const&amp; Rhs)
{
	return Stream.Target &lt;&lt; Rhs;
}
struct Log
{
	std::ostream&amp; Target;
	Log(std::ostream&amp; Target)
		: Target(Target)
	{
	}
};
template&lt;class T&gt;
LogHelper operator&lt;&lt; (Log&amp; Stream, T const&amp; Rhs)
{
	Stream.Target &lt;&lt; Rhs;
	return LogHelper(Stream.Target);
}
Log TollesLog(std::cout);
struct UserDefinedType
{
	float Lhs, Rhs;
	UserDefinedType(float Lhs, float Rhs)
		: Lhs(Lhs), Rhs(Rhs)
	{
	}
};
std::ostream&amp; operator&lt;&lt; (std::ostream&amp; Stream, UserDefinedType const&amp; Rhs)
{
	return Stream &lt;&lt; '(' &lt;&lt; Rhs.Lhs &lt;&lt; '|' &lt;&lt; Rhs.Rhs &lt;&lt; ')';
}
int main()
{
	UserDefinedType Var(5, -5);
	TollesLog &lt;&lt; &quot;Hallo&quot; &lt;&lt; ' ' &lt;&lt; &quot;Welt&quot; &lt;&lt; 123;
	TollesLog &lt;&lt; &quot;Hallo Welt&quot;;
	TollesLog &lt;&lt; &quot;Mein Typ: &quot; &lt;&lt; Var;
}
</code></pre>
<pre><code>Hallo Welt123
Hallo Welt
Mein Typ: (5|-5)
</code></pre>
<p><a href="http://ideone.com/91xUwB" rel="nofollow">http://ideone.com/91xUwB</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360667</guid><dc:creator><![CDATA[not smart]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:10:57 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:12:25 GMT]]></title><description><![CDATA[<p>(macht das selbe wie das von nwp3 aber für jeden typ T und auch ohne klammern nach TollesLog)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360669</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360669</guid><dc:creator><![CDATA[not smart]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:12:25 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:17:37 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Ich verstehe immer noch nicht, wieso du nicht einfach immer wenn geflusht werden soll das auch explizit sagst.</p>
</blockquote>
<p>Aus dem gleichen Grund, warum Log() kein explizites newline am Ende des Strings erfordert: weil man sich nicht ständig unnötig wiederholen will. Es gibt überhaupt keinen Fall, wo nicht geflusht werden soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360672</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360672</guid><dc:creator><![CDATA[raute]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:17:37 GMT</pubDate></item><item><title><![CDATA[Reply to Logging mit ostream on Wed, 16 Oct 2013 10:38:57 GMT]]></title><description><![CDATA[<p>raute schrieb:</p>
<blockquote>
<p>in unserer Software gibt es eine C-Funktion <code>Log(fmtStr, ...)</code> , die bei jedem Aufruf eine Zeile in eine Datei schreibt.<br />
Ich möchte jetzt einen C++-Stream haben, der diese Funktion aufruft.</p>
</blockquote>
<p>Eigentlich ist die Funktions-Syntax besser. Das ist dann ein variadic Makro vor einem variadic Template, das normal in den Stream schreibt und am Ende die Zeile umbricht und flusht. Und man kann das Logging inclusive Auswertung der Log-Argumente abschalten! Ach, Du bist ja auch an so einen Krüppel-Stream geraten.<br />
Viel Spaß mit</p>
<pre><code>debugLog&lt;&lt; &quot;FileExists(\&quot;bla.dat\&quot;)=&quot; &lt;&lt; FileExists(&quot;bla.dat&quot;);
</code></pre>
<p>raute schrieb:</p>
<blockquote>
<p>streambuf gebaut</p>
</blockquote>
<p>raute schrieb:</p>
<blockquote>
<p>Damit kann ich nun</p>
<pre><code class="language-cpp">TollesLog &lt;&lt; &quot;Bla &quot; &lt;&lt; &quot;Blubb&quot;;
</code></pre>
<p>schreiben, und die Ausgabe erscheint im Logfile.</p>
</blockquote>
<p>Ich würde LOG(&quot;Bla&quot;,&quot;Blubb&quot;) nicht völlig ausschließen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2360678</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2360678</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Wed, 16 Oct 2013 10:38:57 GMT</pubDate></item></channel></rss>