C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Streams eigen manipulieren

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Hinnerk Feldwisch
Guest





PostPosted: Tue Oct 25, 2005 2:04 pm    Post subject: Streams eigen manipulieren Reply with quote



Schönen Gruß nochmal,

mein Anliegen von neulich möchte ich nochmal einfacher und von etwas
anderer Sichtweise aus formulieren, in der Hoffnung auf Tips.

Und zwar habe ich eigene Stream- Operatoren für meine Datentypen definiert,
die soweit gut auf den Standard- Streams arbeiten. Jedoch hätte ich gerne
eigene Flags, über die ich die Arbeit der Operatoren verändern kann. Kann
man diese zusätzlich zu jenen der Standard- Flags definieren?
Wohl nicht; was ist dann aber die beste Möglichkeit, dies zu tun? Eigene
Streamklassen abzuleiten, und zu erweitern? Hat jemand evtl. einen
Link/Hinweis auf Literatur dazu?

Herzlichen Dank!,
Hinnerk

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Markus Schaaf
Guest





PostPosted: Tue Oct 25, 2005 3:01 pm    Post subject: Re: Streams eigen manipulieren Reply with quote



"Hinnerk Feldwisch" <usenet1 (AT) hinnerkf (DOT) de> schrieb:

Quote:
Und zwar habe ich eigene Stream- Operatoren für meine Datentypen definiert,
die soweit gut auf den Standard- Streams arbeiten. Jedoch hätte ich gerne
eigene Flags, über die ich die Arbeit der Operatoren verändern kann. Kann
man diese zusätzlich zu jenen der Standard- Flags definieren?

Kann man. Man könnte diese eigenen Daten mittels »xalloc«, »pword« und »iword«
speichern. Ob das jedoch sinnvoll ist, wäre zu bezweifeln.

Quote:
Wohl nicht; was ist dann aber die beste Möglichkeit, dies zu tun? Eigene
Streamklassen abzuleiten, und zu erweitern?

Benutzen könnte man die sicher; ob man dazu ableitet, ist wieder eine andere
Frage.

Quote:
Hat jemand evtl. einen Link/Hinweis auf Literatur dazu?

Suche nach "Serialization" bei Google wäre ein Anfang. Es gibt zu diesem Thema
(zu) viel; man muß eben alles weglassen, was man nicht braucht.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Falk Tannhäuser
Guest





PostPosted: Tue Oct 25, 2005 10:13 pm    Post subject: Re: Streams eigen manipulieren Reply with quote



Hinnerk Feldwisch wrote:
Quote:
Und zwar habe ich eigene Stream- Operatoren für meine Datentypen definiert,
die soweit gut auf den Standard- Streams arbeiten. Jedoch hätte ich gerne
eigene Flags, über die ich die Arbeit der Operatoren verändern kann. Kann
man diese zusätzlich zu jenen der Standard- Flags definieren?
Wohl nicht; was ist dann aber die beste Möglichkeit, dies zu tun? Eigene
Streamklassen abzuleiten, und zu erweitern? Hat jemand evtl. einen
Link/Hinweis auf Literatur dazu?

Das Ableiten von Streamklassen ist deswegen ungünstig, da es dir
nicht gestattet, die Ausgabe deines Datentyps mit den schon
bestehenden Streamklassen zu bewerkstelligen. Wenn zur Ausgabe
zusätzliche, nicht schon in den Objekten des betreffenden Datentyps
bzw. im Streamobjekt (=> Format-Flag) vorhandene Informationen
erforderlich sind, kann man diese in (i.d.R. temporären) Objekten
einer Hilfsklasse stecken, welche man dann statt des "nackten"
Originalobjekts an den Streamausgabeoperator übergibt.

Beispiel: Eine Datumsklasse, für deren Ausgabe ein Formatstring
benötigt wird, um festzulegen, wie das Datum im Stream erscheinen
soll (z.B. mit oder ohne Wochentag, Monat als Zahl, abgekürzter
oder voller Name ...). Diesen String möchte man nicht in jedem
Datum ablegen, und ihn (per xalloc etc.) in den Stream zu stecken
wäre auch zu stressig. Also kann man's z.B. so machen:

class Date
{
public:
// ...
void print(std::ostream& os, char const* format_string) const;
};

struct Date_Formatter
{
Date const& dat;
char const* fmt;
Date_Formatter(Date const& d, char const* f) : dat(d), fmt(f) {}
};

std::ostream& operator<<(std::ostream& os, Date_Formatter const& df)
{
df.dat.print(os, df.fmt);
return os;
}

Benutzt wird das Ganze so:

Date heute;
std::cout << Date_Formatter(d, "Heute ist %A, der %d. %B anno Domini %Y") << 'n';

MfG
Falk

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Werner Salomon
Guest





PostPosted: Sun Oct 30, 2005 4:15 pm    Post subject: Re: Streams eigen manipulieren Reply with quote

Hinnerk Feldwisch wrote:
Quote:
Und zwar habe ich eigene Stream- Operatoren für meine Datentypen definiert,
die soweit gut auf den Standard- Streams arbeiten. Jedoch hätte ich gerne
eigene Flags, über die ich die Arbeit der Operatoren verändern kann. Kann
man diese zusätzlich zu jenen der Standard- Flags definieren?

Hallo Hinnerk,
man kann in Streams eigene Daten einhängen, also auch eigene Flags
definieren.

Quote:
Wohl nicht; was ist dann aber die beste Möglichkeit, dies zu tun? Eigene
Streamklassen abzuleiten, und zu erweitern?
Vom Ableiten von Streams (ostream, istream, usw) um das Ausgabeverhalten

zu ändern, ist abzuraten. Falk hat schon erklärt wieso.
Die User-definierten Daten mittels xalloc, pword und iword sind wohl das
angesagte Mittel.
Hier ein kleines Beispiel mit eigenen Manipulatoren (sieh 'fooX' und
'noFooX'):

#include <iostream>
// -- Foo.h
class Foo // deine Klasse
{
public:
explicit Foo( int x = 0 ) : m_x( x ) {}
friend std::ostream& operator<<( std::ostream& out, const Foo& f );
private:
int m_x;
};

std::ostream& fooX( std::ostream& out ); // die Manipulatoren
std::ostream& noFooX( std::ostream& out );

// -- Foo.cpp
const int OutFlag = std::ios_base::xalloc();

std::ostream& operator<<( std::ostream& out, const Foo& f )
{
if( out.iword( OutFlag ) )
return out << f.m_x << " X'e";
return out << f.m_x;
}
std::ostream& fooX( std::ostream& out )
{
out.iword( OutFlag ) = 1;
return out;
}
std::ostream& noFooX( std::ostream& out )
{
out.iword( OutFlag ) = 0;
return out;
}

// -- Anwendung
int main()
{
using namespace std;
Foo foo( 42 );
cout << "Default: " << foo << endl;
cout << "mit X: " << fooX << foo << endl;
cout << "ohne X: " << noFooX << foo << endl;
return 0;
}

Hat jemand evtl. einen
Quote:
Link/Hinweis auf Literatur dazu?
Hier ist noch ein Beispiel mit pword:



und hier ist im Detail beschrieben, wie man Manipulatoren mit Parametern
erstellt: <http://www.cuj.com/documents/s=7994/cujcexp1906langer/langer.htm>

Gruß
Werner

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
kanze
Guest





PostPosted: Mon Oct 31, 2005 4:48 pm    Post subject: Re: Streams eigen manipulieren Reply with quote

Werner Salomon wrote:

Quote:
Die User-definierten Daten mittels xalloc, pword und iword
sind wohl das angesagte Mittel. Hier ein kleines Beispiel mit
eigenen Manipulatoren (sieh 'fooX' und 'noFooX'):

Es gibt ein grundlegendes Problem mit xalloc und seinen
Krumpeln: man kann nicht wissen, wenn die benutzt werden, und
also kann mann sie auch nie richtig speichern un restorieren.
Z.B., wenn ich etwas mit Formattierung zu tun habe, beginnt die
Funktion meistens:

Gabi::IOSave s( dest ) ;

Also, mit dem Definieren eines Objetes, dessen Destructor die
ursprunglichen Formattierungsdaten auf ihren vorherigen Zustand
zurücksetzt. Nun, diese Klasse kennt nichts von den zusetzlichen
Formattierungs-Daten, und kann sie weder reten noch restorieren.

Ihre Benutzung geht also nur insofern, dass entweder man den
treffenden Manipulator vor jeder Ausgabe benutzt, oder man
stets den Zustand zurücksetzt, wie beim width().

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Dietmar Kuehl
Guest





PostPosted: Tue Nov 01, 2005 9:38 am    Post subject: Re: Streams eigen manipulieren Reply with quote

kanze wrote:
Quote:
Es gibt ein grundlegendes Problem mit xalloc und seinen
Krumpeln: man kann nicht wissen, wenn die benutzt werden, und
also kann mann sie auch nie richtig speichern un restorieren.

Was spricht dagegen, die aktuellen Einstellungen mittels 'copyfmt()'
zu kopieren? Der einzige Grund, der mir einfällt, ist, dass man dafür
ein 'basic_ios'-Objekt braucht, welches nicht ganz billig in der
Erzeugung ist, und durch die Callbacks kann es auch passieren, dass
bei 'copyfmt()' ordentlich was passiert, aber einen semantischen Grund
gibt es nicht.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.de> - Efficient Artificial Intelligence

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
kanze
Guest





PostPosted: Wed Nov 02, 2005 10:12 am    Post subject: Re: Streams eigen manipulieren Reply with quote

Dietmar Kuehl wrote:
Quote:
kanze wrote:
Es gibt ein grundlegendes Problem mit xalloc und seinen
Krumpeln: man kann nicht wissen, wenn die benutzt werden,
und also kann mann sie auch nie richtig speichern un
restorieren.

Was spricht dagegen, die aktuellen Einstellungen mittels
'copyfmt()' zu kopieren? Der einzige Grund, der mir einfällt,
ist, dass man dafür ein 'basic_ios'-Objekt braucht, welches
nicht ganz billig in der Erzeugung ist, und durch die
Callbacks kann es auch passieren, dass bei 'copyfmt()'
ordentlich was passiert, aber einen semantischen Grund gibt es
nicht.

Eigentlich ist dass eine gute Idee. Früher hätte ich gesagt,
dass es nicht in den klassischen Stromen unterstützt wird, und
dabei nicht portabel ist, aber heute denke ich, dass das weniger
ein Problem ist.

Eine Bemerkung aber: was passiert, wenn (exceptions() &
ios_base::badbit) != 0 in der ursprungliche Strom? In einer
naïven Implementierung wird den basic_ios mit einem null-Zeiger
initialisiert; das heißt, dass badbit gesetzt wird. Wenn ich
richtig verstanden habe, dann wird die Exception
basic_ios::failure am Ende von copyfmt gehoben.

Man muss also den basic_ios mit dem streambuf des ursprünglichen
Strom initialisieren:

Gabi::IOSave::IOSave( std::basic_ios<char>& stream )
: myIos( stream.rdbuf() )
{
myIos.copyfmt( stream ) ;
}

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Dietmar Kuehl
Guest





PostPosted: Wed Nov 02, 2005 7:18 pm    Post subject: Re: Streams eigen manipulieren Reply with quote

kanze wrote:
Quote:
Eine Bemerkung aber: was passiert, wenn (exceptions() &
ios_base::badbit) != 0 in der ursprungliche Strom?

Ich hatte das nicht weiter beachtet, aber in diesem Fall gibt es
kein Problem! Was allerdings ein Problem ist, ist wenn
'(rhs.exceptions() & rhs.rdstate()) != 0' gilt: in diesem Fall
wird dann eine Exception geworfen.

Das Vorgehen von 'copyfmt()' ist relativ klar beschrieben: die
verschiedenen Daten werden kopiert und am Ende wir als letztes
'lhs.exceptions(rhs.exeptions())' aufgerufen. Das macht die
Sache in der Tat allerdings nicht einfacher, sondern problematischer,
da man keine Kontrolle über die Zustände in dem ursprüngichen Stream
hat. Ohne try-catch-Block läuft da wohl nichts Sad
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
kanze
Guest





PostPosted: Thu Nov 03, 2005 12:31 pm    Post subject: Re: Streams eigen manipulieren Reply with quote

Dietmar Kuehl wrote:
Quote:
kanze wrote:
Eine Bemerkung aber: was passiert, wenn (exceptions() &
ios_base::badbit) != 0 in der ursprungliche Strom?

Ich hatte das nicht weiter beachtet, aber in diesem Fall gibt
es kein Problem! Was allerdings ein Problem ist, ist wenn
'(rhs.exceptions() & rhs.rdstate()) != 0' gilt: in diesem Fall
wird dann eine Exception geworfen.

Du meinst, dass ein Fehler in rhs schon aufgetreten ist, und
eine Exception aufgelöst hat?

Das Problem, dass ich gesehen habe, ist, dass ich den
speichernden basic_ios initialisieren muss. Und dass die naïv
intuitivsten Initialisierung wäre mit sb == NULL, was badbit
setzt.

Quote:
Das Vorgehen von 'copyfmt()' ist relativ klar beschrieben: die
verschiedenen Daten werden kopiert und am Ende wir als letztes
'lhs.exceptions(rhs.exeptions())' aufgerufen.

Und `lhs.exceptions(rhs.exceptions())' ruft
`lhs.clear(lhs.rdstate())' auf (angeblich nachdem sie die
Attribute gesetzt hat). Und, falls badbit in beiden gesetzt ist,
wirft clear() eine Exception.

Quote:
Das macht die Sache in der Tat allerdings nicht einfacher,
sondern problematischer, da man keine Kontrolle über die
Zustände in dem ursprüngichen Stream hat. Ohne try-catch-Block
läuft da wohl nichts Sad

Ich habe auch überlegt:

Gabi::IOSave::IOSave( std::basic_ios<char>& rhs )
: myIos( NULL )
{
int tmp = rhs.exceptions() ;
rhs.exceptions( ios_base::goodbit ) ;
myIos.copyfmt( rhs ) ;
rhs.exceptions( tmp ) ;
}

Vielleicht auch so etwas beim Restorieren. Ziel meiner
IOSave-Klasse ist, die Formattierung zu restorieren; ich bin
weniger interessiert von locale und überhaupt nicht von
exceptions(). (Ich habe relatif wenig Erfahrung mit Beiden.
Nicht ausreichend, in jedem Fall, um genau zu sagen, was
pragmatisch die beste Lösung wäre. Soll man sie restaurieren?)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.