W
Hallo Eisflamme, hallo SeppJ,
wenn man eine (Text-)Datei im sogenannten DOS-Format vorliegen hat - also mit dem "\r\n" als Zeilenende, dann ist für die Auflösung dieses Zeichenpaars IMHO die std::codecvt-Facette zuständig.
Das geht im Prinzip so:
#include <fstream>
#include <iostream>
#include <locale>
#include <string>
class ConvertCrLf2Lf : public std::codecvt< char, char, int >
{
protected:
virtual bool do_always_noconv() const
{
return false;
}
// -- Einlesen
virtual result do_in( state_type& state,
const extern_type* from, const extern_type* from_end, const extern_type*& from_next,
intern_type* to, intern_type* to_limit, intern_type*& to_next ) const
{
const char CR('\r');
const char LF('\n');
to_next = to;
for( from_next = from; from_next != from_end && 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& state,
// const intern_type* from, const intern_type* from_end, const intern_type*& from_next,
// extern_type* to, extern_type* to_limit, extern_type*& to_next) const { ...
};
int main()
{
using namespace std;
ifstream in("input.txt"/*, ios_base::binary*/ ); // s.u. bei Windows
in.imbue( locale( in.getloc(), new ConvertCrLf2Lf ) );
for( string line; getline( in, line ); )
cout << "> " << line << endl;
return 0;
}
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 codecvt<char,char>-Problem.
Habe i.A. nicht so viel Zeit, noch mehr in die Tiefe zu gehen; mehr zum Thema hatten wir im Forum schon mal hier.
Gruß
Werner