W
imo2 schrieb:
hm das ist auch nicht gerade das was ich suche gibt es nicht irgend einen befehl wie ich einen char als einen anderen ausgebe`?
Einen einzelnen (C++-)Befehl gibt es nicht. Aber man kann sich einen Konverter 'Converter' bauen, demselben mitteilen welche Zeichen in was umgewandelt werden sollen und einen Umschalter (IoSwitch), um den Konverter in die Ausgabe eines ostream's hineinzuhängen .. etwa so:
int main()
{
using namespace std;
Converter cv;
cv.change( 'a', "\\x1#" ); // statt 'a' '\x1#' ausgeben
cv.change( '0', "<->" ); // statt '0' '<->' ausgeben
{
IoSwitch iosw( cout, cv.rdbuf( cout.rdbuf() ) ); // Converter in cout einhängen
cout << "Hallo " << 3 * 34 << endl;
cout << "4 kleine A: aaaa" << endl;
} // <-- im Destruktor von IoSwitch wird hier cout wieder restauriert
cout << "ab hier ist wieder alles normal" << endl;
return 0;
}
Der Converter ist ein std::streambuf. Die Umwandlung passiert in der Methode 'overflow' s.u.
#include <streambuf>
#include <map>
#include <string>
class Converter : public std::streambuf
{
public:
typedef std::streambuf base_type;
typedef base_type::traits_type traits_type;
Converter() : base_type(), m_target( 0 ), m_z() {}
Converter* rdbuf( std::streambuf* target )
{
m_target = target;
return this;
}
void change( char z, const std::string& txt ) { m_z[ z ] = txt; }
protected:
virtual int overflow( int_type x = traits_type::eof() )
{
if( traits_type::eq_int_type( x, traits_type::eof() ) )
return traits_type::not_eof( x );
z_type::iterator i = m_z.find( traits_type::to_char_type( x ) );
if( i != m_z.end() )
{ // Zeichen durch gespeicherten String ersetzen
if( m_target->sputn( i->second.c_str(), std::streamsize( i->second.size() ) )
== i->second.size() )
return traits_type::not_eof( x ); // ok
return traits_type::eof(); // Fehler bei Ausgabe weitergeben
}
return m_target->sputc( x ); // Zeichen einfach weitergeben
}
private:
std::streambuf* m_target;
typedef std::map< char, std::string > z_type;
z_type m_z;
};
und der Umschalter sorgt nach RAII dafür, dass am Ende wieder alles so ist wie vorher
#include <streambuf>
#include <ios>
struct IoSwitch
{
IoSwitch( std::basic_ios< char >& ios_, std::streambuf* sb )
: m_ios( ios_ )
, m_sb( m_ios.rdbuf( sb ) )
{}
~IoSwitch()
{
m_ios.rdbuf( m_sb );
}
private:
std::basic_ios< char >& m_ios;
std::streambuf* m_sb;
// -- Kopieren verhindern
IoSwitch( const IoSwitch& );
IoSwitch& operator=( const IoSwitch& );
};
Falls eine Datei 'a.txt' mit dem gleichen Konverter in eine neue Datei 'b.txt' umgewandelt werden soll, so geht das z.B. so:
Converter cv;
// .. Umwandlungen festlegen (s.o.)
ostream( cv.rdbuf( ofstream( "b.txt" ).rdbuf() ) ) << ifstream( "a.txt" ).rdbuf();
.. noch 10 Tage bis Weihnachten
:xmas2: Werner