<?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 für Anfänger]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich brauche ne kleine Funktion, welche ich so aufrufen will:</p>
<p>log(&quot;dies ist der &quot;+3+&quot;. Test.&quot;+classeVar-&gt;getValue());</p>
<p>Das ganze will ich in eine Datei schreiben, wozu ich einen ofstream (&lt;&lt;) nutze. Irgendwie bin ich zu doof auf den Parameter für die Methode log() zu kommen. Nen Tipp?</p>
<p>Uwe</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/241271/logging-für-anfänger</link><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 16:24:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/241271.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 18 May 2009 14:18:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 14:18:09 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich brauche ne kleine Funktion, welche ich so aufrufen will:</p>
<p>log(&quot;dies ist der &quot;+3+&quot;. Test.&quot;+classeVar-&gt;getValue());</p>
<p>Das ganze will ich in eine Datei schreiben, wozu ich einen ofstream (&lt;&lt;) nutze. Irgendwie bin ich zu doof auf den Parameter für die Methode log() zu kommen. Nen Tipp?</p>
<p>Uwe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712267</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712267</guid><dc:creator><![CDATA[uwerothfeld]]></dc:creator><pubDate>Mon, 18 May 2009 14:18:09 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 14:22:51 GMT]]></title><description><![CDATA[<p>Das ist nicht möglich, sofern nicht einer übergebenen Werte ein selbstdefinierter Typ mit überladenem <code>operator+</code> ist.</p>
<p>Allerdings ist das ziemlicher Java-Stil. In C++ macht man sowas normalerweise über Streams oder ähnliche Klassen, die den <code>operator&lt;&lt;</code> überladen. Zum Beispiel <code>std::clog</code> , das du auch auf Dateien umleiten kannst:</p>
<pre><code class="language-cpp">std::clog &lt;&lt; &quot;dies ist der &quot; &lt;&lt; 3 &lt;&lt; &quot;. Test&quot; &lt;&lt; std::endl;
</code></pre>
<p>Dann kannst du für eigene Typen selbst einen Stream-Operator definieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712268</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 18 May 2009 14:22:51 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 14:30:45 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ja das ist wohl Java Style ;). Das Problem ist, ich habe hier einen Simulator, welcher mir ein macro definiert für die Ausgabe. Da ich diese aber immer gleich haben will, wollte ich mir eine einfache Funktion, log, drumbasteln. Sonst findet man in der Logdatei ja nix wieder. Mh, dann muß ich wohl das Macro umbasteln. Irgendwie unschön, aber sonst fällt mir gerade nix ein.</p>
<p>Danke auf jeden Fall.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712274</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712274</guid><dc:creator><![CDATA[uwerothfeld]]></dc:creator><pubDate>Mon, 18 May 2009 14:30:45 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 14:32:10 GMT]]></title><description><![CDATA[<p>Du kannst auch eine Klasse drumbasteln, die den <code>operator&lt;&lt;</code> überlädt. Wie sieht denn dein Makro aus und was wird als Makro-Parameter erwartet?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712275</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 18 May 2009 14:32:10 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 14:50:55 GMT]]></title><description><![CDATA[<p>ich glaube, du mußt makros UND streams benutzen!<br />
sowas wie</p>
<pre><code class="language-cpp">#define LOG(bla) ofstream(&quot;log.txt&quot;,ios::append)&lt;&lt;time(0)&lt;&lt;' '&lt;&lt;__FILE__&lt;&lt;'('&lt;&lt;__LINE__&lt;&lt;')'&lt;&lt;' '&lt;&lt;bla;
</code></pre>
<p>und später</p>
<pre><code class="language-cpp">LOG(&quot;file not found: &quot;&lt;&lt;path&lt;&lt;'/'&lt;&lt;filename)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1712285</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712285</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 18 May 2009 14:50:55 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 15:01:45 GMT]]></title><description><![CDATA[<p>Also ich habe folgende Klasse (definiert durch den Simulator):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;fstream&gt;
using namespace std;

class DebugInfoWriter 
{
	private:
		static ofstream theFile;
		static string fileName; 

	public:
		DebugInfoWriter(const string &amp; fName);
		static void setDebugFileName(const string &amp; fName);
		static ofstream &amp; getStream(void);
		static void closeStream(void);
};
</code></pre>
<p>und folgendes Macro:</p>
<pre><code class="language-cpp">#define CASTALIA_DEBUG (!printDebugInfo)?(ostream&amp;)DebugInfoWriter::getStream():DebugInfoWriter::getStream()
</code></pre>
<p>Die Lösung von volkard funktioniert ja wieder nur für ne bestimmte anzahl ab vars, aber nicht für elipsen, verschiedener types.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712289</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712289</guid><dc:creator><![CDATA[uwerothfeld]]></dc:creator><pubDate>Mon, 18 May 2009 15:01:45 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 15:16:50 GMT]]></title><description><![CDATA[<p>uwerothfeld schrieb:</p>
<blockquote>
<p>Also ich habe folgende Klasse</p>
</blockquote>
<p>schon klar. das würde bei mir sein</p>
<pre><code class="language-cpp">#define VOLKARDUS_LOG ofstream(&quot;log.txt&quot;,ios::append)
</code></pre>
<blockquote>
<p>Die Lösung von volkard funktioniert ja wieder nur für ne bestimmte anzahl ab vars, aber nicht für elipsen, verschiedener types.</p>
</blockquote>
<p>theoretische grenzen gibts bestimmt, aber ich weiß jetzt nicht, ob die in der praxis stören. praktisch ist, daß ich das logging auch ausschalten kann mit</p>
<pre><code class="language-cpp">#define LOG(bla) ;
</code></pre>
<p>und dann die teuren aufrufe wie in</p>
<pre><code class="language-cpp">LOG(&quot;FreeDiskSpace: &quot;&lt;&lt;getFreeDiskSpace())
</code></pre>
<p>kostenlos werden.</p>
<p>blöd ist aber</p>
<pre><code class="language-cpp">LOG(foo(a,b))
</code></pre>
<p>ob da dafür</p>
<pre><code class="language-cpp">LOG((foo(a,b)))
</code></pre>
<p>geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712294</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712294</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 18 May 2009 15:16:50 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 15:17:09 GMT]]></title><description><![CDATA[<p>uwerothfeld schrieb:</p>
<blockquote>
<p>Die Lösung von volkard funktioniert ja wieder nur für ne bestimmte anzahl ab vars, aber nicht für elipsen, verschiedener types.</p>
</blockquote>
<p>Doch - das macht er ja in seinem Beispiel. Trotzdem finde ich das nicht die sauberste Lösung, aber wohl die einfachste. <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="😉"
    /></p>
<p>Aber dein Makro hat ja nicht Function-Style. Du musst wohl hinten Stream-Operatoren anhängen. Was mir nicht gefällt, ist der Cast. Und etwas mehr Klammern wäre vielleicht sicherer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712295</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712295</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 18 May 2009 15:17:09 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 15:46:19 GMT]]></title><description><![CDATA[<p>Der &quot;übliche&quot; C++ Weg ist eigentlich ein Makro zu basteln, welches sich so verwenden lässt:</p>
<pre><code class="language-cpp">void foo()
{
   LOG() &lt;&lt; &quot;test message&quot; &lt;&lt; 1 &lt;&lt; &quot;, &quot; &lt;&lt; 2 &lt;&lt; &quot;, &quot; &lt;&lt; 3;
}
</code></pre>
<p>Das lässt sich z.B. so machen:</p>
<pre><code class="language-cpp">class LogHelper :
    private boost::noncopyable
{
public:
    explicit LogHelper(char const* filename, size_t lineNumber) :
        m_filename(filename),
        m_lineNumber(lineNumber),
        m_isFlushed(false)
    {
    }

    template &lt;class T&gt;
    LogHelper&amp; operator &lt;&lt; (T const&amp; t)
    {
        m_logStream &lt;&lt; t;
        return *this;
    }

    bool IsFlushed() const
    {
        return m_isFlushed;
    }

    bool IsLogActive() const
    {
        return ...; // true wenn geloggt werden soll
    }

    void Flush()
    {
        std::cout &lt;&lt; m_filename &lt;&lt; &quot; (&quot; &lt;&lt; m_lineNumber &lt;&lt; &quot;): &quot; &lt;&lt; m_logStream.str() &lt;&lt; &quot;\n&quot;;
        m_isFlushed = true;
    }

private:
    std::stringstream m_logStream;
    char const* m_filename; // wir brauchen hier kein std::string, da __FILE__ sowieso ein string-literal ist, den wir nicht kopieren müssen
    size_t m_lineNumber;
    bool m_isFlushed;
};

#define LOG() for (LogHelper __logHelper(__FILE__, __LINE__); __logHelper.IsLogActive() &amp;&amp; !__logHelper.IsFlushed(); __logHelper.Flush()) \
                  __logHelper
</code></pre>
<p>Natürlich kann man das Ganze erweitern indem man z.B. verschiedenen Log-Channels erlaubt, Verbosity-Levels einführt etc. Lässt sich mit diesem System aber alles relativ einfach unterbringen. Auch funktioniert es so wie man es sich erwartet (d.h. auch in if-Abfragen ohne {}). Und der Overhead wenn nicht geloggt wird, ist relativ gering.</p>
<p>Vermutlich könnte man das ganze noch weiter für den &quot;es muss nicht geloggt werden&quot; Fall optimieren, aber für die meisten Anwendungen sollte das so vollkommen ausreichen.</p>
<p>----</p>
<p>Die Version oben erlaubt es dass Exceptions aus dem LOG() Makro rausfliegen, wenn z.B. kein Speicher mehr da ist, oder beim Schreiben ins Logfile irgendwas schief geht. Lässt sich aber auch relativ einfach umbauen, z.B. indem man im operator &lt;&lt; und der Flush() Funktion ein try-catch einbaut, z.B. so:<br />
(meistens will man ja nicht, dass Logging-Funktionen Exceptions werfen, da man die sonst in no-throw Funktionen/Code-Teilen nicht verwenden könnte, oder jedesmal selbst in ein try-catch stecken müsste... und man kann Fehler beim Logging sowieso meist nicht sinnvoll behandeln)</p>
<pre><code class="language-cpp">template &lt;class T&gt;
    LogHelper&amp; operator &lt;&lt; (T const&amp; t)
    {
        try
        {
            m_logStream &lt;&lt; t;
        }
        catch (...)
        {
            m_broken = true;
        }
        return *this;
    }

    void Flush()
    {
        try
        {
            if (!m_broken)
                std::cout &lt;&lt; m_filename &lt;&lt; &quot; (&quot; &lt;&lt; m_lineNumber &lt;&lt; &quot;): &quot; &lt;&lt; m_logStream.str() &lt;&lt; &quot;\n&quot;;
        }
        catch (...)
        {
        }
        m_isFlushed = true;
    }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1712313</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712313</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 18 May 2009 15:46:19 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 17:53:54 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>also ich finde es toll, dass ihr mir so ausführlich helft. das problem ist jedoch: ich nutze einen simulator! da existieren schon zig tausend zeilen code, wo das macro ebenfalls genutzt wird. da muß ich sauber in die gleiche datei schreiben. außerdem steh ich bissl unter zeitnot, und wollte mir das leben einfach bissl einfacher machen. von daher bleib ich bei der volkard lösung, das tut doch ganz schön. vielen dank auf jeden fall. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>uwe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712386</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712386</guid><dc:creator><![CDATA[uwerothfeld_]]></dc:creator><pubDate>Mon, 18 May 2009 17:53:54 GMT</pubDate></item><item><title><![CDATA[Reply to Logging für Anfänger on Mon, 18 May 2009 18:24:11 GMT]]></title><description><![CDATA[<p>STRIKE! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1712411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1712411</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 18 May 2009 18:24:11 GMT</pubDate></item></channel></rss>