<?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[CSS ähnliche Text-Datei parsen]]></title><description><![CDATA[<p>Hallo Forum,</p>
<p>wir haben von der Uni eine CSS ähnliche Datei bekommen, jedoch ist es keine (!) CSS Datei. Es hat eigene Keywords:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/29543">@include</a> &quot;anderePSS.pss&quot;;</p>
<p>/* comment */<br />
[propertyID=&quot;1230000&quot;] {<br />
fillColor : #f3f1ed;<br />
minSize : 5;<br />
lineWidth : 3;<br />
}</p>
<p>/* sphere */<br />
[propertyID=&quot;124???|123000&quot;] {<br />
lineType : dotted;<br />
}</p>
<p>/* square */<br />
[propertyID=&quot;125???&quot;] {<br />
lineType : thinline;<br />
}</p>
<p>/* ring */<br />
[propertyID=&quot;133???&quot;] {<br />
lineType : thickline;<br />
[hasInnerRing=true] {<br />
innerLineType : thinline;<br />
}<br />
}</p>
</blockquote>
<p>Die Datei oben würde ich nun gerne parsen und ich eine MVC überführen. Ich habe das zwar gelöst mit:</p>
<pre><code>QRegExp newBracket = QRegExp(&quot;\\[propertyID=\&quot;.*\&quot;\\]&quot;);
  newBracket.setMinimal(true);
  QRegExp newAttribute = QRegExp(&quot;^\\s*(fillColor|minSize|lineWidth|lineType)\\s*:\\s*([\\w@#]+);&quot;);

  QString currentLine;

  while( currentLine = getNextLine() )
  {
	if (currentLine.contains(newBracket)) 
	{
        QStringList teileZeile = currentLine.split(&quot;=&quot;, QString::SkipEmptyParts);
        columnData &lt;&lt; &quot;PID&quot;;
        columnData &lt;&lt; teileZeile.at(1);
        ++number;
    }
      //
      else if (currentLine.contains(newAttribute)) {
        QStringList teileZeile = currentLine.split(&quot;:&quot;, QString::SkipEmptyParts);
        columnData &lt;&lt; teileZeile.at(0);
        columnData &lt;&lt; teileZeile.at(1);
        ++number;
    }
  }
</code></pre>
<p>Mir wurde gesagt, dass es auf diese Weise nicht sauber wäre (vermutlich weil ich es Zeile für Zeile scanne)? Kann jemand was dazu sagen bzw. kennt jemand eine elegante Lösung?</p>
<p>Ich entwickel mit dem Qt-Framework, jedoch bin ich nicht darauf beschränkt. Dort kenne ich auch nur DOM Parser für XML Formate.<br />
Wenn boost beispielsweise eine dafür predestinierte lib hätte, könnte ich diese sehr gerne einbinden.</p>
<p>Vielen Dank schon mal und VG<br />
Lespaul</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/334150/css-ähnliche-text-datei-parsen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 25 Apr 2026 06:37:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/334150.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 25 Aug 2015 07:42:00 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Tue, 25 Aug 2015 07:47:09 GMT]]></title><description><![CDATA[<p>Hallo Forum,</p>
<p>wir haben von der Uni eine CSS ähnliche Datei bekommen, jedoch ist es keine (!) CSS Datei. Es hat eigene Keywords:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/29543">@include</a> &quot;anderePSS.pss&quot;;</p>
<p>/* comment */<br />
[propertyID=&quot;1230000&quot;] {<br />
fillColor : #f3f1ed;<br />
minSize : 5;<br />
lineWidth : 3;<br />
}</p>
<p>/* sphere */<br />
[propertyID=&quot;124???|123000&quot;] {<br />
lineType : dotted;<br />
}</p>
<p>/* square */<br />
[propertyID=&quot;125???&quot;] {<br />
lineType : thinline;<br />
}</p>
<p>/* ring */<br />
[propertyID=&quot;133???&quot;] {<br />
lineType : thickline;<br />
[hasInnerRing=true] {<br />
innerLineType : thinline;<br />
}<br />
}</p>
</blockquote>
<p>Die Datei oben würde ich nun gerne parsen und ich eine MVC überführen. Ich habe das zwar gelöst mit:</p>
<pre><code>QRegExp newBracket = QRegExp(&quot;\\[propertyID=\&quot;.*\&quot;\\]&quot;);
  newBracket.setMinimal(true);
  QRegExp newAttribute = QRegExp(&quot;^\\s*(fillColor|minSize|lineWidth|lineType)\\s*:\\s*([\\w@#]+);&quot;);

  QString currentLine;

  while( currentLine = getNextLine() )
  {
	if (currentLine.contains(newBracket)) 
	{
        QStringList teileZeile = currentLine.split(&quot;=&quot;, QString::SkipEmptyParts);
        columnData &lt;&lt; &quot;PID&quot;;
        columnData &lt;&lt; teileZeile.at(1);
        ++number;
    }
      //
      else if (currentLine.contains(newAttribute)) {
        QStringList teileZeile = currentLine.split(&quot;:&quot;, QString::SkipEmptyParts);
        columnData &lt;&lt; teileZeile.at(0);
        columnData &lt;&lt; teileZeile.at(1);
        ++number;
    }
  }
</code></pre>
<p>Mir wurde gesagt, dass es auf diese Weise nicht sauber wäre (vermutlich weil ich es Zeile für Zeile scanne)? Kann jemand was dazu sagen bzw. kennt jemand eine elegante Lösung?</p>
<p>Ich entwickel mit dem Qt-Framework, jedoch bin ich nicht darauf beschränkt. Dort kenne ich auch nur DOM Parser für XML Formate.<br />
Wenn boost beispielsweise eine dafür predestinierte lib hätte, könnte ich diese sehr gerne einbinden.</p>
<p>Vielen Dank schon mal und VG<br />
Lespaul</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2465471</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2465471</guid><dc:creator><![CDATA[lespaul]]></dc:creator><pubDate>Tue, 25 Aug 2015 07:47:09 GMT</pubDate></item><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Tue, 25 Aug 2015 14:51:35 GMT]]></title><description><![CDATA[<p><a href="http://www.boost.org/doc/libs/1_59_0/libs/spirit/doc/html/index.html" rel="nofollow">boost Spirit</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2465539</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2465539</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Tue, 25 Aug 2015 14:51:35 GMT</pubDate></item><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Tue, 25 Aug 2015 19:43:42 GMT]]></title><description><![CDATA[<p>lespaul schrieb:</p>
<blockquote>
<p>Mir wurde gesagt, dass es auf diese Weise nicht sauber wäre (vermutlich weil ich es Zeile für Zeile scanne)?</p>
</blockquote>
<p>Nein, weil du mit Regexp nur reguläre Grammatiken erkennen kannst, und das schaut nicht nach einer aus. Zu Lexern und Parsern gibts genug Theorie, deswegen gibts genügend sauberere Methoden, als das mit Regexp hinzupfuschen.<br />
Ich weiß nicht, ob ich boost::spirit empfehlen würde, hab damit zumindest keine Erfahrung. Ich hätte wahrscheinlich einfach einen recursive descent Parser von Hand geschrieben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2465591</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2465591</guid><dc:creator><![CDATA[Mechanics]]></dc:creator><pubDate>Tue, 25 Aug 2015 19:43:42 GMT</pubDate></item><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Thu, 27 Aug 2015 19:17:58 GMT]]></title><description><![CDATA[<p>lespaul schrieb:</p>
<blockquote>
<p>.. Mir wurde gesagt, dass es auf diese Weise nicht sauber wäre (vermutlich weil ich es Zeile für Zeile scanne)? Kann jemand was dazu sagen bzw. kennt jemand eine elegante Lösung?</p>
</blockquote>
<p>Hallo Lespaul,</p>
<p>Zeile für Zeile lesen ist selten eine gute Idee. Zumal das Format anscheinend in keiner Weise zeilenorientiert ist.<br />
Das kann man auch mit C++-Hausmitteln lösen. Etwa so:</p>
<pre><code>#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;map&gt;
#include &lt;vector&gt;
#include &lt;list&gt;

template&lt; char C &gt;
std::istream&amp; Char( std::istream&amp; in )
{
    char c;
    if( in &gt;&gt; c &amp;&amp; c != C )
        in.setstate( std::ios_base::failbit );
    return in;
}

class Entry
{
public:
    // einlesen eines Eintrags
    friend std::istream&amp; operator&gt;&gt;( std::istream&amp; in, Entry&amp; prop );

private:
    std::string token_, id_;
    std::map&lt; std::string, std::string &gt; values_;
    std::list&lt; Entry &gt; subProperties_;
};

// Kommentar und Zeilen ab '@' überlesen
std::istream&amp; comment( std::istream&amp; in )
{
    for( char c; in &gt;&gt; c; )
    {
        if( c == '/' )
        {
            in &gt;&gt; Char&lt;'*'&gt;;
            enum class Mode { Idle, StarFound, End };
            for( auto mode = Mode::Idle; mode != Mode::End &amp;&amp; in &gt;&gt; c; )
            {
                switch( mode )
                {
                case Mode::Idle:
                    if( c == '*' )
                        mode = Mode::StarFound;
                    break;

                case Mode::StarFound:
                    if( c == '/' )
                        mode = Mode::End;   // Kommentar überlesen
                    else if( c != '*' )
                        mode = Mode::Idle;
                    break;
                }
            }
        }
        else if( c == '@' )
            in.ignore( 999, '\n' ); // skip line
        else
            return in.putback( c );
    }
    return in;
}

// einen Eintrag lesen
std::istream&amp; operator&gt;&gt;( std::istream&amp; in, Entry&amp; prop )
{
    // Format:                               [         token    =          id    ]             {
    getline( getline( in &gt;&gt; comment &gt;&gt; Char&lt;'['&gt;, prop.token_, '=' ), prop.id_, ']' ) &gt;&gt; Char&lt;'{'&gt;; 
    decltype(Entry::values_) values;
    decltype(Entry::subProperties_) subProperties;
    for( char c; in &gt;&gt; c &amp;&amp; c != '}'; )
    {
        if( in.putback(c) &amp;&amp; c == '[' )
        {
            Entry p;
            if( in &gt;&gt; p )
                subProperties.emplace_back( std::move(p) );
        }
        else
        {
            std::string key, value;
            if( getline( in &gt;&gt; key &gt;&gt; Char&lt;':'&gt; &gt;&gt; std::ws, value, ';' ) )
                values.emplace( std::move(key), std::move(value) );
        }
    }
    if( in )
    {
        prop.values_ = std::move( values );
        prop.subProperties_ = std::move( subProperties );
    }
    return in;
}

int main()
{
    using namespace std;
    ifstream file(&quot;input.txt&quot;);
    if( !file.is_open() )
    {
        cerr &lt;&lt; &quot;Fehler beim Oeffnen der Datei&quot; &lt;&lt; endl;
        return -2;
    }
    vector&lt; Entry &gt; entries;
    for( Entry prop; file &gt;&gt; prop; )
        entries.emplace_back( prop );

    cout &lt;&lt; entries.size() &lt;&lt; &quot; Eintraege gelesen&quot; &lt;&lt; endl;
    if( !file.eof() )
        cerr &lt;&lt; &quot;Fehler beim Lesen&quot; &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2465876</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2465876</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 27 Aug 2015 19:17:58 GMT</pubDate></item><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Tue, 01 Sep 2015 10:32:15 GMT]]></title><description><![CDATA[<pre><code>getline( getline( in &gt;&gt; comment &gt;&gt; Char&lt;'['&gt;, prop.token_, '=' ), prop.id_, ']' ) &gt;&gt; Char&lt;'{'&gt;;
</code></pre>
<p>Und du checkst solche Zeilen auch nach paar Wochen noch ? Krass</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2466442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2466442</guid><dc:creator><![CDATA[hu??]]></dc:creator><pubDate>Tue, 01 Sep 2015 10:32:15 GMT</pubDate></item><item><title><![CDATA[Reply to CSS ähnliche Text-Datei parsen on Tue, 01 Sep 2015 10:35:09 GMT]]></title><description><![CDATA[<pre><code>// Format:                               [         token    =          id    ]             {
</code></pre>
<p>Dieser Kommentar ist dabei ziemlich hilfreich finde ich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2466443</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2466443</guid><dc:creator><![CDATA[kommentar]]></dc:creator><pubDate>Tue, 01 Sep 2015 10:35:09 GMT</pubDate></item></channel></rss>