<?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[Eigenes getline?]]></title><description><![CDATA[<p>Hi,</p>
<p>ich bastele gerade ein eigenes getline, das auch schon bei '\r' ohne '\n' stoppt, weil ich eine komische Datei habe.</p>
<p>Das funktioniert auch ganz gut, nur dass er die letzte Zeile nicht liest, weil das !myGetline gilt und die Schleife daher abbricht. Beispiel:</p>
<pre><code class="language-cpp">istream&amp; getlineUntilLinebreakOrCarriage(istream &amp; in, string&amp; out)
{
	out.clear();
	char c;
	while(!in.eof() &amp;&amp; in.get(c).good())
	{
		if(c == '\r')
		{
			c = in.peek();
			if(in.good() &amp;&amp; c == '\n')
				in.ignore();
			break;
		}
		else if(c == '\n')
			break;

		out.append(1, c);
	}

	return in;
}

int main()
{
	ifstream ifs(&quot;C:/test/easyTest.txt&quot;);

	string str;
	int n = 0;
	while(getlineUntilLinebreakOrCarriage(ifs, str))
	{
		cout &lt;&lt; n++ &lt;&lt; &quot;: &quot; &lt;&lt; str &lt;&lt; '\n' &lt;&lt; flush;
	}

	cout &lt;&lt; &quot;Read all: &quot; &lt;&lt; n &lt;&lt; &quot; lines.\n&quot;;

	int x;
        cin &gt;&gt; x;
        return 0;
}
</code></pre>
<p>Ausgabe:</p>
<pre><code>0: Hallo
Read all: 1 lines.
</code></pre>
<p>easyTest.txt:</p>
<pre><code>Hallo
Du!
</code></pre>
<p>Wahrscheinlich wieder so ein richtig dummer Fehler. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/291317/eigenes-getline</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 00:03:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/291317.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Aug 2011 12:11:10 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 12:11:10 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich bastele gerade ein eigenes getline, das auch schon bei '\r' ohne '\n' stoppt, weil ich eine komische Datei habe.</p>
<p>Das funktioniert auch ganz gut, nur dass er die letzte Zeile nicht liest, weil das !myGetline gilt und die Schleife daher abbricht. Beispiel:</p>
<pre><code class="language-cpp">istream&amp; getlineUntilLinebreakOrCarriage(istream &amp; in, string&amp; out)
{
	out.clear();
	char c;
	while(!in.eof() &amp;&amp; in.get(c).good())
	{
		if(c == '\r')
		{
			c = in.peek();
			if(in.good() &amp;&amp; c == '\n')
				in.ignore();
			break;
		}
		else if(c == '\n')
			break;

		out.append(1, c);
	}

	return in;
}

int main()
{
	ifstream ifs(&quot;C:/test/easyTest.txt&quot;);

	string str;
	int n = 0;
	while(getlineUntilLinebreakOrCarriage(ifs, str))
	{
		cout &lt;&lt; n++ &lt;&lt; &quot;: &quot; &lt;&lt; str &lt;&lt; '\n' &lt;&lt; flush;
	}

	cout &lt;&lt; &quot;Read all: &quot; &lt;&lt; n &lt;&lt; &quot; lines.\n&quot;;

	int x;
        cin &gt;&gt; x;
        return 0;
}
</code></pre>
<p>Ausgabe:</p>
<pre><code>0: Hallo
Read all: 1 lines.
</code></pre>
<p>easyTest.txt:</p>
<pre><code>Hallo
Du!
</code></pre>
<p>Wahrscheinlich wieder so ein richtig dummer Fehler. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106323</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106323</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 12:11:10 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 12:23:38 GMT]]></title><description><![CDATA[<p>Also ein Fehler der mir sofort ins Auge fällt:<br />
Wenn die Datei mit einem Carriage Return endet, dann prüfst du in der Schleife, ob danach noch ein Zeichen kommt. Das ist aber nicht der Fall, der Stream wird somit ungültig, weil du ja über das Ende des Streams hinausschauen wolltest und wenn du den Stream danach zurückgibst, ist er ungültig und die letzte Zeile wird ignoriert. Problem liegt somit sicher schonmal bei Zeile 9.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106327</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106327</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Aug 2011 12:23:38 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 12:38:02 GMT]]></title><description><![CDATA[<p>Stimmt!<br />
Das hier sollte das fixen, oder?</p>
<pre><code class="language-cpp">istream&amp; getlineUntilLinebreakOrCarriage(istream &amp; in, string&amp; out)
{
	out.clear();
	char c;
	while(!in.eof() &amp;&amp; in.get(c).good())
	{
		if(c == '\r')
		{
			c = in.peek();
			if(in.good() &amp;&amp; c == '\n')
				in.ignore();
			in.clear(); // Löscht das failbit
			break;
		}
		else if(c == '\n')
			break;

		out.append(1, c);
	}

	return in;
}
</code></pre>
<p>Oder ist das aus irgendwelchen Gründen unsauber?</p>
<p>Leider beseitigt das mein Problem noch nicht. In meinem einfachen Beispiel endet die Datei auch mit \r\n, daher setzt peek kein failbit. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106339</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106339</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 12:38:02 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:33:41 GMT]]></title><description><![CDATA[<p>Darf ich mal in eine ganz andere Kerbe hauen?</p>
<p>Vorteile: IO geht so wie gewohnt, keine Notwendigkeit spezielle Funktionen zu benutzen oder irgendetwas umzuschreiben:</p>
<pre><code class="language-cpp">#include &lt;boost/iostreams/filtering_stream.hpp&gt;
#include &lt;boost/iostreams/device/file.hpp&gt;
#include &lt;boost/iostreams/categories.hpp&gt; 
#include &lt;boost/iostreams/operations.hpp&gt; 

#include &lt;iostream&gt;
#include &lt;string&gt;

namespace io = boost::iostreams;

struct line_feed_to_new_line
{
  typedef char              char_type;
  typedef io::input_filter_tag  category;

  template&lt;typename Source&gt;
  int get(Source&amp; src)
        {
          int c = io::get(src);
          return c == '\r' ? '\n': c;
        }
};

int main()
{  
    io::filtering_istream in;
    in.push(line_feed_to_new_line());
    in.push(io::file_source(&quot;test.dat&quot;));  // Eine Datei, die gemischte Zeilenumbrüche enthält

    int i=0;
    std::string out;
    while(getline(in,out)) std::cout &lt;&lt; &quot;Zeile &quot; &lt;&lt; i++ &lt;&lt; &quot;: &quot; &lt;&lt; out &lt;&lt;'\n';
}
</code></pre>
<p>Ist jetzt mit einem Einzelzeichenfilter nur als Demo gedacht, vielleicht reicht dir das schon. Falls Performance wichtig ist, programmier lieber einen Filter, der mehrere Zeichen auf einmal verarbeitet, z.B. einen multi_character_input_filter oder (falls es kein Problem ist, die ganze Datei im Speicher zu halten) einen aggregate_filter.</p>
<p>Oder guck mal den Quellcode des Boost newline-Filters an. Der sollte das nämlich eigentlich schon machen. Aber funktionierte bei mir nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106355</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106355</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:33:41 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:21:57 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a>,<br />
Dein Programm macht doch aber etwas anderes, nicht? Es verwertet <code>\r</code> und <code>\n</code> Endungen käme aber mit <code>\r\n</code> Endungen nicht klar, weil es da eine leere Zeile erzeugen würde.</p>
<p>Und was soll dieses <code>c == 11 ? '\n': c;</code> ? Ein Vergleich auf 11? Also bitte <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>Ich würde allerdings auch überlegen, einen anderen Lösungsweg zu wählen. Habe mir auch überlegt, ob man da nicht was über <code>streambuf</code> machen könnte. Der Stream soll ja nur ungültig werden, wenn es einen fatalen Fehler gibt ( <code>badbit</code> ) oder er bereits am Anfang am Ende steht. Wenn während dem Lesen das Ende erreicht wird, soll er noch nicht auf einen ungültigen Zustand gesetzt werden. <code>failbit</code> dürfte eigentlich nie auftauchen.</p>
<p>Wenn die Testdatei von Eisflamme nun aus genau 2 Zeilen besteht und am Ende keine leere Zeile zu finden ist, wird die Funktion von Eisflamme nicht funktionieren. Seine Lösung ignoriert immer die letzte Zeile, weil dann das <code>eofbit</code> gesetzt ist.</p>
<p>Aber habe gerade zu wenig Zeit, mich da reinzuwühlen ...</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106366</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106366</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:21:57 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:34:17 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Und was soll dieses <code>c == 11 ? '\n': c;</code> ? Ein Vergleich auf 11? Also bitte <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>
</blockquote>
<p>Ach, da habe ich mich selbst verarscht. Ich habe erst eine Textdatei getippt und dann im Hexeditor die 10en (\n) durch 11en ersetzt. Und mich dann gewundert, warum ein Vergleich mit '\r' nicht klappt. Dabei ist '\r' eine 13!</p>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /> Ich hab's oben editiert, damit eventuelle Leser das nicht falsch übernehmen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /></p>
<p>Hmm, \r\n, gar nicht an die Windows-Konvention gedacht. Sollte nicht so schwer sein, dies auch noch abzufangen. Entweder über eine statische Helfervariable oder wenn man, wie ohnehin schon vorgeschlagen, einen der Filter implementiert, der gleich die ganze Sequenz vorliegen hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106371</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106371</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:34:17 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:32:45 GMT]]></title><description><![CDATA[<p>Ich will ja nur getline nachbauen mit einem kleinen Unterschied... eigentlich kann das doch nicht so schwierig sein, oder? Weeerner ^^</p>
<p>Ich habe Mal in der MSVC-Implementierung nachgeschaut, aber die scheint leider nicht so simpel gestrickt zu sein wie das, was ich mache. Achso und vielen Dank für die boost-Lösung, aber ich denke, das hier sollte sich auch mit Standardmitteln gut machen lassen (hoffe ich).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106372</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106372</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:32:45 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:36:15 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Ich will ja nur getline nachbauen mit einem kleinen Unterschied... eigentlich kann das doch nicht so schwierig sein, oder? Weeerner ^^</p>
</blockquote>
<p>Im Prinzip ist das was Werner immer mit seinen Wunder-Streambufs macht, genau das was Boost::iostreams abstrahiert hat. Die haben eben einmal so einen Standard-Streambuffer geschrieben, den man beliebig mit eigenen Filterobjekten füttern kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106375</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106375</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:36:15 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:37:29 GMT]]></title><description><![CDATA[<p>Ja, das ist auf Dauer auch sicher nicht schlecht anzugucken. Ich könnte auch deinen Code übernehmen ohne mir die Details anzuschauen. Aber da ich gerade so ein wenig anfange die Streams zu verstehen, halte ich es für sinnvoller den Block erstmal näher zu verstehen bis ich dann auf die boost-Abstraktion wechsle. <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>Hoffe, meine Motive schockieren oder beleidigen niemanden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106376</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:37:29 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 13:43:58 GMT]]></title><description><![CDATA[<p>Ev. hilft dir folgendes Schnipsel (zusammengeschustert aus Threads in denen Werner was gepostet hat):</p>
<pre><code class="language-cpp">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;
}

template &lt;char C, typename T&gt;
std::istream&amp; read_until(std::istream&amp; in, T&amp; v)
{
    return in &gt;&gt; v &gt;&gt; Char&lt;C&gt;;
}

template &lt;char C&gt;
std::istream&amp; read_until(std::istream&amp; in, std::string&amp; s)
{
    return std::getline(in, s, C);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2106382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106382</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Mon, 15 Aug 2011 13:43:58 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 14:03:53 GMT]]></title><description><![CDATA[<p>Sieht sehr interessant aus, auch wenn ich nicht genau verstehe, was passiert, wenn man eine Funktion an einen istream übergibt. Und die <a href="http://cplusplus.de/reference" rel="nofollow">cplusplus.de/reference</a> ist in dem Punkt auch zu knapp (oder ich hab was übersehen).</p>
<p>Mein erster Versuch ist:</p>
<pre><code class="language-cpp">istream&amp; Breaker(istream&amp; in)
{
	char c;
	if(in &gt;&gt; c &amp;&amp; c != '\r' &amp;&amp; c != '\n')
		in.setstate(ios_base::failbit);
	return in;
}

istream&amp; customGetline(istream&amp; in, string&amp; str)
{
	return in &gt;&gt; str &gt;&gt; Breaker;
}

int main()
{
	ifstream ifs(&quot;C:/test/easyTest.txt&quot;);

	string str;
	int n = 0;
	//while(getlineUntilLinebreakOrCarriage(ifs, str))
	while(customGetline(ifs, str))
	{
		cout &lt;&lt; n++ &lt;&lt; &quot;: &quot; &lt;&lt; str &lt;&lt; '\n' &lt;&lt; flush;
	}

	cout &lt;&lt; &quot;Read all: &quot; &lt;&lt; n &lt;&lt; &quot; lines.\n&quot;;

	int x;

	cin &gt;&gt; x;
}
</code></pre>
<p>Dieser führt leider zu nichts, keine einzige Zeile wird gelesen. Auch wenn ich statt != das intuitivere == benutze (im Breaker) erhalte ich nur eine Zeile. (Natürlich würde der Code mein Problem auch nicht lösen, ich will damit nur sagen, dass ich nicht Mal ansatzweise dahinkomme, wo ich hinwill ^^)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106391</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106391</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 14:03:53 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 14:12:34 GMT]]></title><description><![CDATA[<p>Ha:<br />
<a href="http://www.cplusplus.com/reference/iostream/ios/operatornot/" rel="nofollow">http://www.cplusplus.com/reference/iostream/ios/operatornot/</a></p>
<blockquote>
<p>Returns true if either one of the error flags (failbit or badbit) is set on the stream. Otherwise it returns false.</p>
</blockquote>
<p>operator! stört sich nicht an eof, das darauffolgende get erzeugt aber ein fail. Damit sollte sich das Problem lösen lassen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106396</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106396</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 14:12:34 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 14:58:34 GMT]]></title><description><![CDATA[<p>So, dieser Hack funktioniert:</p>
<pre><code class="language-cpp">istream&amp; getlineUntilLinebreakOrCarriage(istream &amp; in, string&amp; out)
{
	out.clear();
	char c;

	if(in.eof())
	{
		in.setstate(ios_base::eofbit | ios_base::failbit);
		return in;
	}

	while(!in.eof() &amp;&amp; in.get(c).good())
	{
		if(c == '\r')
		{
			c = in.peek();
			if(in.good() &amp;&amp; c == '\n')
				in.ignore();
			in.clear();
			break;
		}
		else if(c == '\n')
			break;

		out.append(1, c);
	}

	if(in.eof())
	{
		in.clear();
		in.setstate(ios_base::eofbit);
	}

	return in;
}
</code></pre>
<p>in hat erst nen good-State, dann nutzt man get und er setzt gleichzeitig das failbit und das eofbit... um das zu erreichen, was ich möchte, lösche ich also das failbit einmal raus und überprüfe am Anfang auf das eof-Bit...</p>
<p>Aber das ist auch hässlich. Weiß hier niemand, wie man das &quot;richtig&quot; macht? <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2106411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106411</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 15 Aug 2011 14:58:34 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 15:18:37 GMT]]></title><description><![CDATA[<p>Mittlerweile habe ich genug von Werner gelernt, dass ich so etwas auch selber programmieren kann. So sollte es sauber sein, ganz ohne Hacks:</p>
<pre><code class="language-cpp">#include &lt;streambuf&gt; // Die beiden brauchen wir, hoffentlich habe ich nichts vergessen
#include &lt;istream&gt;     
#include &lt;fstream&gt;   // Die anderen drei sind nur für das Beispiel
#include &lt;string&gt;
#include &lt;iostream&gt;

class char_filter : public std::streambuf
{
public:
  char_filter(std::istream&amp; in, char from, char to )
    : in(in) // Stream merken, um später den Streambuf wiederherstellen zu können
    , buf (in.rdbuf())   // Der Original-Streambuf. Daher kommen unsere Daten
    , from(traits_type::to_int_type(from)), to(traits_type::to_int_type(to)) // Für die Filterfunktion, immer schön abstrakt bleiben
  {
    in.rdbuf(this);  // Unseren Streambuf installieren
  }
  ~char_filter()
  {
    in.rdbuf(buf); // alten Streambuf wieder herstellen
  }

protected:
  virtual int_type underflow()  // Eine der Funktionen die ein istream benutzen könnte (und die tatsächlich etwas lesen) und die wir darum überschreiben möchten
  {
    int_type c = buf-&gt;sgetc();
    return (traits_type::eq_int_type( c, from )) ? to : c;  // Immer schön abstrakt bleiben bei den Typen und Abfragen
  }
  virtual int_type uflow()      // Die andere Funktion die drankommen könnte
  {
    int_type c = buf-&gt;sbumpc();
    return (traits_type::eq_int_type( c, from )) ? to : c;
  }
private:
  char_filter( const char_filter&amp; );            // Macht den Streambuffer unkopierbar
  char_filter&amp; operator=( const char_filter&amp; ); // Sonst geht das mit dem Merken des unterliegenden Streams schief

  std::istream&amp; in;
  std::streambuf* buf;
  int_type from, to;
};

int main()
{
  std::ifstream ifs(&quot;test.dat&quot;);
  char_filter foo(ifs, '\r', '\n'); // So lange foo lebt, wird ifs gefiltert
  // Das kann man natürlich auch anders handhaben, wie der Filter genau installiert wird, aber so ist ganz praktisch.

  int i=0;
  std::string out;
  while(getline(ifs,out)) std::cout &lt;&lt; &quot;Zeile &quot; &lt;&lt; i++ &lt;&lt; &quot;: &quot; &lt;&lt; out &lt;&lt;'\n'; 
}
</code></pre>
<p>Wie schon zuvor, überlasse ich die Sonderbehandlung von \r\n dem geneigten Leser. Mit dieser Vorgabe sollte es trivial zu erweitern sein.</p>
<p>P.S.: Und ich könnte viel schneller mit so etwas sein, wenn ich den Hex-Editor richtig bedienen könnte, um mir passende Beispiele zu erstellen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /> .</p>
<p>edit: Sehr viele Edits: Die Kommentare verbessert</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106416</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106416</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 15:18:37 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 15:26:04 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a>: beeindruckend! <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2106425</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106425</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Mon, 15 Aug 2011 15:26:04 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 15:39:19 GMT]]></title><description><![CDATA[<p>theta schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a>: beeindruckend! <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>
</blockquote>
<p>Alles bei Werner Salomon gelernt <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2106432</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106432</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 15:39:19 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 17:15:30 GMT]]></title><description><![CDATA[<p>Ich verstehe alles außer underflow und uflow. (die wohl overflow heißen sollte?)<br />
Kann mir das jemand erklären? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106466</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106466</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Mon, 15 Aug 2011 17:15:30 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 17:23:57 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Ich verstehe alles außer underflow und uflow. (die wohl overflow heißen sollte?)<br />
Kann mir das jemand erklären? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
</blockquote>
<p>Nein, overflow() ist etwas anderes (das spielt bei den Ausgaben vor). Beide Funktionen werden verwendet, wenn der interne Zwischenspeicher zu Ende ist, wobei sich ein paar Randbedingungen unterscheiden, wann welche benötigt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106470</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106470</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 15 Aug 2011 17:23:57 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 18:06:45 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Ich verstehe alles außer underflow und uflow. (die wohl overflow heißen sollte?)<br />
Kann mir das jemand erklären? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
</blockquote>
<p>Das wie und warum dazu findest du wiederum hier:<br />
<a href="http://www.cplusplus.com/reference/iostream/streambuf/" rel="nofollow">http://www.cplusplus.com/reference/iostream/streambuf/</a><br />
Da sehen wir erst einmal oben die public-Member. Diese haben wir geerbt. Die verwalten irgendwie intern einen Puffer (ist ja ein Streambuf <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="😉"
    /> ) und stellen dem Stream ein Interface zur Verfügung. Der Stream wird nun diese Funktionen benutzen, um aus dem Puffer zu lesen. Und jetzt sieht du vielleicht schon, warum das Underflow heißt: Wenn der interne Puffer (unser Puffer!) leer gelesen ist, dann müssen neue Zeichen rein. Die Standardimplementierung dieser Funktionen (die wir tunlichst nicht überschreiben sollten!) ruft dann die passenden virtual-Memberfunktionen auf. underflow, wenn der Puffer neue Zeichen braucht und overflow wenn der Puffer voll ist (im Falle eines ostreams).<br />
Es gibt auch eine Reihe weiterer virtueller Funktionen, aber wenn du die Beschreibungen liest, wirst du sehen, dass diese eine brauchbare Defaultimplementierung haben und einfach wieder die anderen Memberfunktionen aufrufen. Die wichtigen Funktionen sind die, die ich überschrieben habe (und overflow für Ausgabestreambufs), die per Default überhaupt nichts tun, außer Fehlerwerte zurück zu geben. Für so einen einfachen Filterstream wie diesen reicht das völlig aus. Wenn's etwas anspruchsvoller sein soll, kann man sich die anderen Funktionen auch mal näher ansehen.</p>
<p>So, nun wissen wir aber gar nicht, woher wir unsere Zeichen bekommen sollen. Und selbst wenn wir es wüssten, dann würde ich ungern die Funktionen zum Lesen aus Dateien nachbauen. Daher habe ich mir den alten Streambuf gemerkt. Da braucht man gar nicht wissen, was da genau dahinter steht. Dessen public-Memberfunktionen funktionieren für uns genau so gut wie für den ursprünglichen fstream. Wenn also jemand unseren Streambuf nach Zeichen fragt und unser interner Puffer leer ist, dann fragen wir einfach den alten Strambuf nach Zeichen und filtern diese. Was danach damit passiert oder wie das intern gehandhabt wird kann uns egal sein. Wir sitzen mit unseren virtuellen Funktionen an der Schlüsselstelle, wo jeder vorbei muss.</p>
<p>P.S.: Möglich, dass der Default-Streambuf gar keinen internen Puffer hat. Die Beschreibung von setbuf klingt irgendwie danach. Ich bin nicht so der Experte auf dem Gebiet. Egal, der Filebuf den wir intern benutzen wird sicherlich richtig gepuffert sein.</p>
<p>P.P.S.: Danke für die Frage, ich glaube ich habe das Gesamtkonzept gerade selber das erste Mal richtig verstanden. Ursprünglich stand hier eine ganz andere Erklärung wie ich es mir vorher vorgestellt habe, bis ich bei genauerem Nachdenken gemerkt habe, dass das gar nicht stimmen konnte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106487</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106487</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 15 Aug 2011 18:06:45 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Mon, 15 Aug 2011 18:29:34 GMT]]></title><description><![CDATA[<p>Danke für die Erklärung, wird schon etwas klarer <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2106493</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106493</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Mon, 15 Aug 2011 18:29:34 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 07:53:15 GMT]]></title><description><![CDATA[<p>Hey ho,</p>
<p>sauber SeppJ, vielen Dank, das hat mir schon enorm weitergeholfen. <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>Ich habe jetzt folgenden Fall: Es kann sein, dass '\r' alleine vorkommt, '\n' alleine vorkommt oder '\r' nebst '\n' vorkommt. Ich muss also weg von der Einzeichen-Basis.</p>
<p>So wie ich das sehe, lässt sich das folgendermaßen umsetzen:<br />
- '\r' nebst '\n' löse ich, indem ich nach Lesen von '\r' schaue, ob das nächste Zeichen '\n' ist und, falls ja, den get-Zeiger einfach weiterschiebe und '\n' zurückgebe<br />
- '\r' ohne '\n' wird gelöst, indem ich beim Lesen von '\r' einfach '\n' zurückgebe und den get-Zeiger normal lasse (einfache Konvertierung)<br />
- '\n' wird als normales Zeichen zurückgegeben</p>
<p>Dann lässt sich das normale getline wieder anwenden. Ist folgender Code wohl in Ordnung?</p>
<pre><code class="language-cpp">custom_streambuf::int_type custom_streambuf::underflow()
{
	int_type c = oldBuf.sgetc();

	if(traits_type::eq_int_type(c, 13)) // c == '\r'
	{
		// Are characters to read and is next one '\n'?
		if(in_avail() == 0)
			return traits_type::int_type(10); // '\n';
		int_type c2 = oldBuf.snextc(); // move pointer to next element

		if(traits_type::eq_int_type(c2, 10))
			return c2;

		// here: c2 != '\n', so we should move back
		oldBuf.sungetc();
	}

	// In case of '\n' or other digits, we can return just them
	return c;
}

custom_streambuf::int_type custom_streambuf::uflow()
{
	int_type c = oldBuf.sbumpc();

	if(traits_type::eq_int_type(c, 13)) // c == '\r'
	{
		// We are at the next character; is it '\n'?
		int_type c2 = oldBuf.sgetc();

		if(traits_type::eq_int_type(c2, 10)) // it is '\n', so we should move to next token but return '\n'
		{
			snextc();
			return c2;
		}

		// here: c2 != '\n', so this get-pointer place is just right
	}

	// In case of '\n' or other digits, we can return just them
	return c;
}
</code></pre>
<p>Ich bin nicht ganz sicher, ob dieses in_avail genau macht, was ich möchte, laut Doku liest es ja die Anzahl der noch zu lesenden Zeichen, auch falls der interne Puffer gerade leer ist, aus. Wenn das also &gt;0 ist, kommt noch was, ansonsten ist wohl eof | fail der Fall.</p>
<p>Mein initiales Beispiel &quot;Hallo Du!&quot; funktioniert damit übrigens. Seht ihr irgendwelche Fehler?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106622</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106622</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 16 Aug 2011 07:53:15 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 08:35:59 GMT]]></title><description><![CDATA[<p>Ich würde nicht mit in_avail() arbeiten. Das ist oftmals so implementiert, dass es einfach 0 liefert, weil der Streambuf gar nicht wissen kann, wie viel noch kommt (woher soll er z.B. wissen wie viel der Anwender noch tippen wird, wenn er an der Tastatur hängt?). Was du tun könntest, wäre, auf EOF zu prüfen (siehe z.B <a href="http://www.c-plusplus.net/forum/p1655736#1655736" rel="nofollow">hier wie das geht</a>). Aber ich würde das etwas simpler machen: Du hast eine Klasse, die kann auch einen Zustand haben. Wenn '\r' kommt, setzt du dir einen bool-Member, und wenn '\n' kommt, dann guckst du ob der bool gesetzt ist und verwirfst das Zeichen gegebenenfalls.</p>
<p>Ungetestet:</p>
<pre><code class="language-cpp">class CRLF_filter : public std::streambuf
{
public:
  CRLF_filter(std::istream&amp; in)
    : in(in) 
    , buf (in.rdbuf())  
  {
    in.rdbuf(this);
  }
  ~CRLF_filter()
  {
    in.rdbuf(buf); 
  }

protected:
  virtual int_type underflow() 
  {
    int_type c = buf-&gt;sgetc();
    if (traits_type::eq_int_type( c, LF ) &amp;&amp; last_was_CR)
     {
      int_type c = buf-&gt;snextc();  // Nächstes Zeichen nehmen
      last_was_CR = false;      
     }
    if (traits_type::eq_int_type( c, CR ))
     {
       c = LF;
       last_was_CR = true;
     }
    return c; 
  }
  virtual int_type uflow()    
  {
    int_type c = buf-&gt;sbumpc();
    if (traits_type::eq_int_type( c, LF ) &amp;&amp; last_was_CR)
     {
      int_type c = buf-&gt;sbumpc();  // Man beachte den Unterschied zu oben
      last_was_CR = false;      
     }
    if (traits_type::eq_int_type( c, CR ))
     {
       c = LF;
       last_was_CR = true;
     }
    return c; 
  }
private:
  char_filter( const char_filter&amp; ); 
  char_filter&amp; operator=( const char_filter&amp; ); 

  std::istream&amp; in;
  std::streambuf* buf;
  static const int_type CR, LF;
  bool last_was_CR;
}; 

CRLF_filter::int_type CRLF_filter::LF  = CRLF_filter::traits_type::to_int_type('\n');
CRLF_filter::int_type CRLF_filter::CR = CRLF_filter::traits_type::to_int_type('\r');
</code></pre>
<p>So, ich hoffe, ich habe da keine Dummheiten gemacht, die man erst bei Sonderfällen wie \r\EOF oder ähnlichem bemerkt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106632</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106632</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 16 Aug 2011 08:35:59 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 08:44:10 GMT]]></title><description><![CDATA[<p>Hast Recht, das ist eigentlich viel einfacher und v.a. sicherer. <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>Aber wenn \r\EOF endet, gilt last_was_CR; wenn ich die nächste Datei lese und die mit \n anfängt, wird das \n ignoriert. Können wir das noch irgendwie lösen?</p>
<p>Hm... wobei ich gerade überlege, ob dieser Fall überhaupt eintritt, <em>ohne</em> dass wir ein neues istream-Objekt haben..</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106638</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106638</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 16 Aug 2011 08:44:10 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 08:57:53 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Hm... wobei ich gerade überlege, ob dieser Fall überhaupt eintritt, <em>ohne</em> dass wir ein neues istream-Objekt haben..</p>
</blockquote>
<p>Theoretisch könnte der Nutzer das Filterobjekt auch an einen anderen Stream binden, aber da wir keine Schnittstelle zur Verfügung stellen, kann er den Streambuf der unter unserem Stream liegt nicht ändern. Theoretisch könnte er diesen manipulieren, aber wer so etwas tut, soll auch mit den Konsequenzen leben. Das ist schließlich ein absichtlicher Hack. Und es wäre selbst dann auch konsistent: Der Streambuf filtert \r zu \n und \r\n zu \n. Woher die Zeichen kommen, sollte unserem Filter egal sein.</p>
<p>Jedenfalls brauchst du keine Angst zu haben, dass dir das bei normaler Benutzung passiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106643</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106643</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 16 Aug 2011 08:57:53 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 09:15:11 GMT]]></title><description><![CDATA[<p>Ok, prima. <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>Ich habe jetzt ein paar Tests gemacht. Hier 5 Dateien:</p>
<pre><code>48 61 6C 6C 6F 0A 44 75 21
48 61 6C 6C 6F 0D 44 75 21
48 61 6C 6C 6F 0D 44 75 0D 0A
48 61 6C 6C 6F 0D 44 75 0A
48 61 6C 6C 6F 0D 44 75 0D
</code></pre>
<p>(\r \n in der Mitte hatte ich vorher schon Mal getestet, das geht auch)</p>
<p>Ich erzeuge jeweils einen neuen istream und auch Buffer. Für diese fünf Dateien funktioniert alles. <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="🙂"
    /><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Ein paar Kleinigkeiten habe ich im Code noch geändert, weil z.B. das lastCR-Flag bei normalen Zeichen nach \r nicht geändert wurde und so. Zur Vollständigkeit nochmal der Code:</p>
<pre><code class="language-cpp">custom_streambuf::int_type custom_streambuf::underflow()
{
	int_type c = oldBuf.sgetc();

	if(traits_type::eq_int_type(c, LF) &amp;&amp; lastWasCR) // \r\n -&gt; we are at \n
	{
		lastWasCR = false;
		// Ignore this
		return oldBuf.snextc();
	}
	if(traits_type::eq_int_type(c, CR)) // \r -&gt; we memorize this but return \n
	{
		lastWasCR = true;
		return LF;
	}
	lastWasCR = false;

	return c;
}

custom_streambuf::int_type custom_streambuf::uflow()
{
	int_type c = oldBuf.sbumpc();

	if(traits_type::eq_int_type(c, LF) &amp;&amp; lastWasCR) // \r\n -&gt; we are at \n
	{
		lastWasCR = false;
		// Ignore this
		return oldBuf.sbumpc();
	}
	if(traits_type::eq_int_type(c, CR)) // \r -&gt; we memorize this but return \n
	{
		lastWasCR = true;
		return LF;
	}
	lastWasCR = false;

	return c;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2106648</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106648</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Tue, 16 Aug 2011 09:15:11 GMT</pubDate></item><item><title><![CDATA[Reply to Eigenes getline? on Tue, 16 Aug 2011 20:37:53 GMT]]></title><description><![CDATA[<p>Hallo Eisflamme, hallo SeppJ,</p>
<p>wenn man eine (Text-)Datei im sogenannten DOS-Format vorliegen hat - also mit dem &quot;\r\n&quot; als Zeilenende, dann ist für die Auflösung dieses Zeichenpaars IMHO die <a href="http://www.cplusplus.com/reference/std/locale/codecvt/" rel="nofollow">std::codecvt-Facette</a> zuständig.</p>
<p>Das geht im Prinzip so:</p>
<pre><code class="language-cpp">#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;locale&gt;
#include &lt;string&gt;

class ConvertCrLf2Lf : public std::codecvt&lt; char, char, int &gt;
{
protected:
    virtual bool do_always_noconv() const
    {
        return false;
    }
    // -- Einlesen
    virtual result do_in( state_type&amp; state,
        const extern_type* from, const extern_type* from_end, const extern_type*&amp; from_next,
        intern_type* to, intern_type* to_limit, intern_type*&amp; to_next ) const
    {
        const char CR('\r');
        const char LF('\n');
        to_next = to;
        for( from_next = from; from_next != from_end &amp;&amp; to_next != to_limit; ++from_next )
        {
            switch( state )
            {
            case 0: // normal
                if( *from_next == CR )
                    state = 1; // wir merken uns nur, dass CR da war
                else
                    *to_next++ = *from_next;
                break;

            case 1: // das vorherige Zeichen war CR
                if( *from_next != LF )
                {
                    *to_next++ = CR; // allein stehendes CR nachliefern
                    if( to_next == to_limit )
                        return std::codecvt_base::partial;
                }
                if( *from_next != CR )
                {
                    *to_next++ = *from_next;
                    state = 0;
                }
            }
        }
        return from_next == from_end? std::codecvt_base::ok: std::codecvt_base::partial;
    }
    // -- Ausgeben
    // virtual result do_out(stateT&amp; state,
    //   const intern_type* from, const intern_type* from_end, const intern_type*&amp; from_next,
    //   extern_type* to, extern_type* to_limit, extern_type*&amp; to_next) const { ...
};

int main()
{
    using namespace std;
    ifstream in(&quot;input.txt&quot;/*, ios_base::binary*/ );  // s.u. bei Windows
    in.imbue( locale( in.getloc(), new ConvertCrLf2Lf ) );
    for( string line; getline( in, line ); )
        cout &lt;&lt; &quot;&gt; &quot; &lt;&lt; line &lt;&lt; endl;
    return 0;
}
</code></pre>
<p>Die Facette kann mit imbue an den Stream und damit an den Streambuf übergeben werden. Jeder basic_filebuf sollte auch was damit anfangen können. Bei Windows-Systemen ist das aber nie notwendig; dort reicht es die Datei im Textmode zu öffnen - d.h. ohne das binary (s.o.). Wenn man es unter Windows ausprobieren will, so muss die Datei binär geöffnet werden und - ganz wichtig - VC10 benutzen, da die älterne Versionen einen Fehler haben - siehe <a href="http://connect.microsoft.com/VisualStudio/feedback/details/361058/error-in-fstream-when-using-a-char-char-custom-codecvt-destroyed-characters" rel="nofollow">codecvt&lt;char,char&gt;-Problem</a>.</p>
<p>Habe i.A. nicht so viel Zeit, noch mehr in die Tiefe zu gehen; mehr zum Thema hatten wir im Forum schon mal <a href="http://www.c-plusplus.net/forum/p1356758" rel="nofollow">hier</a>.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2106993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2106993</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Tue, 16 Aug 2011 20:37:53 GMT</pubDate></item></channel></rss>