<?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[Programmierung von ConfigReader&#x2F;Parser]]></title><description><![CDATA[<p>Hi,<br />
ich würde gerne in Teamarbeit mit einigen schon fortgeschrittenen(!) Leuten eine Bibliothek schreiben die es ermöglicht Konfigurationsdatein auszulesen. Die Werte sollen dann im Programm verwendbar sein.</p>
<p>Ich habe das ganze schon soweit fertig programmiert, suche nun aber noch Leute die mir helfen noch folgendes zu erledigen:<br />
- Optimierung damit die Geschwindigkeit des Ladens einer Datei noch geringer wird und der Speicherverbrauch auch<br />
- Das Interface flexibler machen um damit angenehmer und effektiver arbeiten zu können<br />
- Bessere Fehlerbehandlung...<br />
- Das ganze in eine Bibliothek verpacken<br />
- Evtl. noch weitere Funktionen die uns einfallen einbauen...</p>
<p>Jetzt zur eigentlichen Konfigurationsdatei. Eine Beispieldatei würde z.B. so aussehen wobei die Tiefe der Blöcke - intern Tabs genannt - nur durch den Speicher begrenz ist:</p>
<pre><code class="language-cpp">&quot;Block1&quot;
{
   &quot;Wert1&quot; = &quot;Test&quot;;
   &quot;Wert2&quot; = 1234;

   &quot;Block2&quot;
   {
      &quot;Wert1&quot; = &quot;Test&quot;;
      &quot;Wert2&quot; = 1234;

      &quot;Block3&quot;
      {
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      };
   }
};

&quot;Block2&quot;
{
   &quot;Wert1&quot; = &quot;Test&quot;;
   &quot;Wert2&quot; = 1234;

   &quot;Block3&quot;
   {
      &quot;Wert1&quot; = &quot;Test&quot;;
      &quot;Wert2&quot; = 1234;

      &quot;Block4&quot;
      {
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      };
   }
};
</code></pre>
<p>Der Zugriff aus einem C++ Programm gefällt mir jedenfalls noch nicht, aber das würde z.Z. so aussehen:</p>
<pre><code class="language-cpp">PC0 P( &quot;Datei.pc0&quot; );
PC0Tab *Main = P.GetMainTab();
PC0Tab *Block1 = Main-&gt;Search( &quot;Block1&quot; );
PC0Tab *Block2 = Block1-&gt;Search( &quot;Block2&quot; );
PC0Tab *Wert1 = Block2-&gt;Search( &quot;Wert1&quot; );
std::cout &lt;&lt; Wert1-&gt;GetValues().Name &lt;&lt; &quot; = &quot; &lt;&lt; Wert1-&gt;GetValues().Value &lt;&lt; std::endl;
</code></pre>
<p>Nun fragt man sich natürlich: Warum nutzt man nicht XML? Also ich persönlich mag XML nicht und finde es irgendwie sehr unübersichtlich.</p>
<p>Okay, ich hoffe ich habe nun alles erwähnt was ich erwähnen wollte, falls noch Fragen bestehen bitte melden <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>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/159629/programmierung-von-configreader-parser</link><generator>RSS for Node</generator><lastBuildDate>Thu, 10 Sep 2026 16:04:17 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/159629.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 17 Sep 2006 12:33:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Sun, 17 Sep 2006 12:36:49 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich würde gerne in Teamarbeit mit einigen schon fortgeschrittenen(!) Leuten eine Bibliothek schreiben die es ermöglicht Konfigurationsdatein auszulesen. Die Werte sollen dann im Programm verwendbar sein.</p>
<p>Ich habe das ganze schon soweit fertig programmiert, suche nun aber noch Leute die mir helfen noch folgendes zu erledigen:<br />
- Optimierung damit die Geschwindigkeit des Ladens einer Datei noch geringer wird und der Speicherverbrauch auch<br />
- Das Interface flexibler machen um damit angenehmer und effektiver arbeiten zu können<br />
- Bessere Fehlerbehandlung...<br />
- Das ganze in eine Bibliothek verpacken<br />
- Evtl. noch weitere Funktionen die uns einfallen einbauen...</p>
<p>Jetzt zur eigentlichen Konfigurationsdatei. Eine Beispieldatei würde z.B. so aussehen wobei die Tiefe der Blöcke - intern Tabs genannt - nur durch den Speicher begrenz ist:</p>
<pre><code class="language-cpp">&quot;Block1&quot;
{
   &quot;Wert1&quot; = &quot;Test&quot;;
   &quot;Wert2&quot; = 1234;

   &quot;Block2&quot;
   {
      &quot;Wert1&quot; = &quot;Test&quot;;
      &quot;Wert2&quot; = 1234;

      &quot;Block3&quot;
      {
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      };
   }
};

&quot;Block2&quot;
{
   &quot;Wert1&quot; = &quot;Test&quot;;
   &quot;Wert2&quot; = 1234;

   &quot;Block3&quot;
   {
      &quot;Wert1&quot; = &quot;Test&quot;;
      &quot;Wert2&quot; = 1234;

      &quot;Block4&quot;
      {
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      };
   }
};
</code></pre>
<p>Der Zugriff aus einem C++ Programm gefällt mir jedenfalls noch nicht, aber das würde z.Z. so aussehen:</p>
<pre><code class="language-cpp">PC0 P( &quot;Datei.pc0&quot; );
PC0Tab *Main = P.GetMainTab();
PC0Tab *Block1 = Main-&gt;Search( &quot;Block1&quot; );
PC0Tab *Block2 = Block1-&gt;Search( &quot;Block2&quot; );
PC0Tab *Wert1 = Block2-&gt;Search( &quot;Wert1&quot; );
std::cout &lt;&lt; Wert1-&gt;GetValues().Name &lt;&lt; &quot; = &quot; &lt;&lt; Wert1-&gt;GetValues().Value &lt;&lt; std::endl;
</code></pre>
<p>Nun fragt man sich natürlich: Warum nutzt man nicht XML? Also ich persönlich mag XML nicht und finde es irgendwie sehr unübersichtlich.</p>
<p>Okay, ich hoffe ich habe nun alles erwähnt was ich erwähnen wollte, falls noch Fragen bestehen bitte melden <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>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1138996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1138996</guid><dc:creator><![CDATA[Dummie]]></dc:creator><pubDate>Sun, 17 Sep 2006 12:36:49 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Sun, 17 Sep 2006 14:08:15 GMT]]></title><description><![CDATA[<p>Schau dir mal boost::spirit an, damit müsstest du das recht gut parsen können.</p>
<p>Pseudo spiritcode:</p>
<pre><code class="language-cpp">using namespace boost::spirit;
rule&lt;&gt; rvar= *alnum_p &gt;&gt; &quot;=&quot; &gt;&gt; *alnum_p;
rule&lt;&gt; rblock = *alnum_p &gt;&gt; &quot;{&quot; &gt;&gt; *(rblock|rvar) &gt;&gt; &quot;};&quot;;
rule&lt;&gt; rfile = +rblock;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1139025</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1139025</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Sun, 17 Sep 2006 14:08:15 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Sun, 17 Sep 2006 14:31:23 GMT]]></title><description><![CDATA[<p>Hi,<br />
das mag sein, dass sich das damit gut parsen lässt, aber darum gehts nicht ich habs schon ohne geschafft ich suche nurnoch Leute die mir helfen die Oben genannten Punkte abzuarbeiten.</p>
<p>Das Interesse scheint jetzt aber noch nciht so groß zu sein</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1139043</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1139043</guid><dc:creator><![CDATA[Dummie]]></dc:creator><pubDate>Sun, 17 Sep 2006 14:31:23 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Sun, 17 Sep 2006 15:25:58 GMT]]></title><description><![CDATA[<p>Dieser Thread wurde von Moderator/in <a href="http://www.c-plusplus.net/forum/profile.php?mode=viewprofile&amp;u=4180" rel="nofollow">Korbinian</a> aus dem Forum <a href="http://www.c-plusplus.net/forum/viewforum.php?f=11" rel="nofollow">Projekte</a> in das Forum <a href="http://www.c-plusplus.net/forum/viewforum.php?f=15" rel="nofollow">C++</a> verschoben.</p>
<p>Im Zweifelsfall bitte auch folgende Hinweise beachten:<br />
<a href="http://www.c-plusplus.net/forum/viewtopic.php?t=39405" rel="nofollow">C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?</a></p>
<p><em>Dieses Posting wurde automatisch erzeugt.</em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1139070</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1139070</guid><dc:creator><![CDATA[C++ Forumbot]]></dc:creator><pubDate>Sun, 17 Sep 2006 15:25:58 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Sun, 17 Sep 2006 17:44:38 GMT]]></title><description><![CDATA[<p>Hallo Dummie,</p>
<p>also ich wäre interessiert an dem Projekt. Wollte so etwas auch mal schreiben/nutzen habe dann aber keine Zeit dafür gehabt.<br />
Normalerweiße programmie ich in c, anscheinend ist es in cpp geschrieben, sollte aber kein allzu großes Problem darstellen.</p>
<p>Schreib mir doch einfach mal an blubb email Addresse entfernt.</p>
<p>Gruß<br />
yogle</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1139094</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1139094</guid><dc:creator><![CDATA[yogle]]></dc:creator><pubDate>Sun, 17 Sep 2006 17:44:38 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Mon, 18 Sep 2006 22:06:22 GMT]]></title><description><![CDATA[<p>Hi,<br />
sowas in der Art hatte ich damals auch mal angefangen allerdings entspricht dein Ansatz eher dem was bei XML DOM entsprechen würde und dass was ich da damals zusammengeflickt hatte würde eher dem Eventbasierten SAX entsprechen(basiert auch auf nem Artikel über nen einfachen Sax Parser <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 />
Insgesamt ist der Aufbau deiner Config Datei allerdings nem XML File doch sehr ähnlich und ich sehe da momentan auch keinen grossen Grund warum du deshalb auf die Annehmlichkeiten fertiger XML Parser wie XercesC oder MSXML verzichtest und dich statt dessen lieber selber auf die Suche nach geschweiften Klammern machst.<br />
Naja der Punkt steht ja anscheinend auch nicht zur Debatte.<br />
Ich hab meinen damaligen Code mal etwas umgestrickt dass er bei leicht abgewandelter Syntax deines Config Formats nen halbwegs brauchbares Ergebnis liefert.<br />
Unterm Strich muss man für nen spezifisches Configfile nur ne Klasse von configuration_base ableiten und in der init Methode die Assoziation zwischen dem Key(welcher dem kompletten Pfad bis zum Wert entspricht) und der dazugehörigen Variablen herstellen.</p>
<p>Also:<br />
<strong>config_element.h</strong></p>
<pre><code class="language-cpp">#ifndef __CONFIG_ELEMENT_H
#define __CONFIG_ELEMENT_H

#include &lt;string&gt;

class config_element
{
public:
  virtual void put(const std::string&amp; s) const=0;
  virtual ~config_element() {}
};
#endif
</code></pre>
<p><strong>config_element_data.h</strong></p>
<pre><code class="language-cpp">#ifndef __CONFIG_ELEMENT_DATA_H
#define __CONFIG_ELEMENT_DATA_H

#include &lt;sstream&gt;
#include &lt;string&gt;
#include &quot;config_element.h&quot;

template&lt;typename T&gt;
class config_element_data : public config_element
{
public:
    config_element_data(T&amp; item) : ref_(item){}
    virtual void put(const std::string&amp; s)const
    {
        std::istringstream stream(s);
        stream &gt;&gt; ref_;
    }
private:
    T&amp; ref_;
};

#endif
</code></pre>
<p>Und noch configuration_base.h(Implementierung mit in die Klassendeklaration gestopft).</p>
<pre><code class="language-cpp">#ifndef __CONFIGURATION_BASE_H
#define __CONFIGURATION_BASE_H

#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;map&gt;
#include &lt;stack&gt;
#include &lt;sstream&gt;
#include &quot;config_element.h&quot;

class configuration_base
{
    typedef std::map&lt;std::string,config_element* &gt; config_map_t;
public:
	configuration_base(){_path.push(&quot;&quot;);}
    virtual ~configuration_base()
    {
        config_map_t::iterator it = config_map.begin();
        while(it != config_map.end())
		{
            delete (*it).second;
			it++;
		}
    }

    void loadConfiguration(const char* filename)
    {
        std::ifstream ifstr(filename);
        if(ifstr)
        {
            std::string buf;
            while(std::getline(ifstr,buf))
			{
				static std::string _last_buf=&quot;&quot;;

				std::string::size_type pos = buf.find_first_not_of(' ');
				if(pos != std::string::npos)
					buf = buf.substr(pos);

				if(buf==&quot;{&quot;)
				{
					std::string temp = _path.top();
					temp += _last_buf;
					temp.insert(temp.end(),'/');
					_path.push(temp);
				}
				else 
					if(buf==&quot;}&quot;)
						_path.pop();
					else
						setValue(buf);
				_last_buf=buf;
			}
            ifstr.close();
        }
    }
protected:
    config_map_t config_map;
	std::stack&lt;std::string&gt; _path;

    bool setValue(const std::string &amp;s)
    {
        std::istringstream isstr(s);
        std::string valueName;
        std::string value;
        isstr&gt;&gt;valueName;
        isstr&gt;&gt;value;
		std::string str = _path.top();
		str += valueName;
        config_map_t::iterator it;
        it = config_map.find(str);
        if(it!=config_map.end())
        {
            (*it).second-&gt;put(value);
            return true;
        }
        else
            return false;
    }
private:
    virtual void init() = 0;
};

#define CONFIG_ENTRY(Keyname,DataType,VarName) config_map.insert(std::make_pair(std::string(Keyname),new config_element_data&lt;DataType&gt;(VarName)));

#endif
</code></pre>
<p>Und dann noch was zum Testen:<br />
<strong>demo_configuration.h</strong>(die einzige Klasse die man neu schreiben müsste)</p>
<pre><code class="language-cpp">#ifndef __DEMO_CONFIG_H
#define __DEMO_CONFIG_H

#include &quot;config_element_data.h&quot;
#include &quot;configuration_base.h&quot;

class demo_configuration : public configuration_base
{
public:
    int block1_wert1;
    double block2_wert2;
    std::string name;
	std::string wert45;
	int dummy;
	float dummy2;

    demo_configuration()
    {
		//eventuell mit Standardwerten belegen
        block1_wert1=0;
        block2_wert2=0.0;
		dummy=12;
        name=&quot;Default&quot;;
		wert45=&quot;Default&quot;;
		dummy2=12.34;

        init();
    }
private:
    void init()
    {
        config_map.insert(std::make_pair(std::string(&quot;Block1/Wert1&quot;),new config_element_data&lt;int&gt;(block1_wert1)));
        config_map.insert(std::make_pair(std::string(&quot;Block2/Wert2&quot;),new config_element_data&lt;double&gt;(block2_wert2)));
        config_map.insert(std::make_pair(std::string(&quot;Name&quot;),new config_element_data&lt;std::string&gt;(name)));
		//oder für die Schreibfaulen
		CONFIG_ENTRY(&quot;dummy2&quot;,float,dummy2)
		CONFIG_ENTRY(&quot;dummy&quot;,int,dummy)
		CONFIG_ENTRY(&quot;Block2/Block3/Block4/Wert45&quot;,std::string,wert45)
    }
};

#endif
</code></pre>
<p><strong>main.cpp</strong></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &quot;demo_configuration.h&quot;

int main()
{
    demo_configuration config;

	std::cout&lt;&lt;&quot;Vor dem laden:&quot;&lt;&lt;std::endl;
    std::cout&lt;&lt;config.name&lt;&lt;std::endl;
	std::cout&lt;&lt;config.block1_wert1&lt;&lt;std::endl;
	std::cout&lt;&lt;config.block2_wert2&lt;&lt;std::endl;
	std::cout&lt;&lt;config.dummy&lt;&lt;std::endl;
	std::cout&lt;&lt;config.wert45&lt;&lt;std::endl;
	std::cout&lt;&lt;config.dummy2&lt;&lt;std::endl;

	config.loadConfiguration(&quot;conf.txt&quot;);

	std::cout&lt;&lt;&quot;\nNach dem laden:&quot;&lt;&lt;std::endl;
    std::cout&lt;&lt;config.name&lt;&lt;std::endl;
	std::cout&lt;&lt;config.block1_wert1&lt;&lt;std::endl;
	std::cout&lt;&lt;config.block2_wert2&lt;&lt;std::endl;
	std::cout&lt;&lt;config.dummy&lt;&lt;std::endl;
	std::cout&lt;&lt;config.wert45&lt;&lt;std::endl;
	std::cout&lt;&lt;config.dummy2&lt;&lt;std::endl;

	return 0;
}
</code></pre>
<p>und die Config Datei:</p>
<pre><code>Name	Teststring
Block1
{
   Wert1 567
   Wert2 1234

   Block2
   {
      Wert1 Test
      Wert2 

      Block3
      {
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      }
   }
}

dummy 7

Block2
{
   Wert1 Test
   Wert2 3.14

   Block3
   {
      Wert1 Test
      Wert2 1234

      Block4
      {
	 Wert45 Telefonmann
         /*
           Und so weiter...
           Kommentare sind also möglich sowohl Mehrzeilig als auch Einzeilig(//)
         */
      }
   }
}

dummy2 34.38
</code></pre>
<p>Die Fehlerbehandlung fehlt fast vollständig und gescheit getestet ist das Ganze auch nicht aber im Gegensatz zu dir möchte ich ja auch keine Lib schreiben <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="😃"
    /> .<br />
Also schau dir das Ganze mal an.Eventuell findest du da ja die eine oder andere Anregung.</p>
<p>Gruss Spacelord</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1140053</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1140053</guid><dc:creator><![CDATA[Spacelord]]></dc:creator><pubDate>Mon, 18 Sep 2006 22:06:22 GMT</pubDate></item><item><title><![CDATA[Reply to Programmierung von ConfigReader&#x2F;Parser on Tue, 19 Sep 2006 06:32:45 GMT]]></title><description><![CDATA[<p>phlox81 schrieb:</p>
<blockquote>
<p>Schau dir mal boost::spirit an, damit müsstest du das recht gut parsen können.</p>
<p>Pseudo spiritcode:</p>
<pre><code class="language-cpp">using namespace boost::spirit;
rule&lt;&gt; rvar= *alnum_p &gt;&gt; &quot;=&quot; &gt;&gt; *alnum_p;
rule&lt;&gt; rblock = *alnum_p &gt;&gt; &quot;{&quot; &gt;&gt; *(rblock|rvar) &gt;&gt; &quot;};&quot;;
rule&lt;&gt; rfile = +rblock;
</code></pre>
</blockquote>
<p>Ich habe spirit mittlerweile wieder verbannt. Es ist zwar recht angenehm die Syntax runter zu schreiben, aber den Aufwand den ich dort spare muss ich dann meist doppelt aufwenden um überhaupt an die geparsten Werte zu kommen. Für komplexe Sachen ist ohnehin flex/bison besser geeignet und für einfache Sachen ist ein handgeschriebener Parser auch kein Beinbruch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1140097</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1140097</guid><dc:creator><![CDATA[Walli]]></dc:creator><pubDate>Tue, 19 Sep 2006 06:32:45 GMT</pubDate></item></channel></rss>