Re: STL-Streams und Unicode/UTF-16
- From: Ulrich Eckhardt <eckhardt@xxxxxxxxxxxxxx>
- Date: Tue, 27 Jun 2006 16:07:57 +0200
Andreas Heyer wrote:
"Christoph Rabel" <crabel@xxxxxxxxx> wrote:
Um Flexibilität und Erweiterbarkeit zu erreichen. d.h. nicht, dass ein
Template von Haus aus eine Eierlegende Wollmilchsau ist.
Mhm, im Moment genügt es aber nicht mal elementaren Dingen!
Natuerlich, RTFM bzw Standard, da drin steht wie es funktionieren soll und
das tut es auch. Ja ich weiss, es ist nicht so wie Du willst, aber es ist
wenigstens ueberall gleich, unter Debian mit ICC, unter FreeBSD mit GCC
oder unter Windows mit VC6 und STLport.
Das Problem ist, dass Zeichensätze und Konvertierungen ein wahnsinnig
komplexes Thema sind.
Nur wenn man jedes Byte auch als Text behandeln will!
Streams sind per Definition/Design textbasiert. D.h., die interne
Schnittstelle setzt Text voraus, in der Form von char oder wchar_t um genau
zu sein. Extern setzt das ganze Bytes voraus (implementiert im Typ char,
was von zweifelhafter Eleganz ist). Dazwischen konvertiert ein Plugin (jep,
zur Laufzeit austauschbar!) welches einem groestmoegliche Freiheit darin
gibt wie man seine internen Zeichen als externe Bytes dargestellt haben
will.
Wo ist Dein Problem mit diesem Design? Die Trennung von interner und
externer Darstellung ist IMHO gelungen.
Durch den Standard ist ja eine Lösung vorgesehen, indem man eine
eigene Facette schreibt und diese dem Stream gibt. Nur wurde das im
Rahmen der Norm halt nicht gemacht und hinzugefügt.
Für mich ist dann aber der einzige logische Templateparameter die
Facette!
Ich habe eine Menge Code der einfach in einen wostream schreibt, was dann
extern (und ohne dass dieser Code davon wissen braucht!) ASCII, UTF-8 oder
eins von diversen anderen Formaten erhaelt. Waere das externe Format ein
Template-Parameter so waehre der schreibende Code entweder ebenfalls ein
Template oder aber fuer diverse Formate ueberladen (bei ansonsten gleichem
Inhalt). Fazit: fuer mich kaeme es als Template-Parameter nicht in
betracht.
Wie von Ulrich herausgefunden, wird beim Instanzieren mit dem
FILE-Pointer keine Facette gesetzt. Also irgendwie verstehe ich das
nicht: wenn der Stream auch ohne Facette funktioniert, warum setzt man
dann standardmäßig so eine dumme Version, die nicht das macht, was viele
erwarten?
Der Pointer der da gesetzt wird ist ein Implementierungsdetail und ein
Nullpointer (soweit ich das sehen konnte) signalisiert das die Facette eine
memcpy()-gleiche Operation macht und das wird dann wegoptimiert. Wie ich
gelesen habe scheint das sogar eine Dinkuware-spezifische Sache zu sein,
ist also eventuell nichtmal portabel. Ansonsten hat jeder char- und
wchar_t- Stream immer eine Lokale in der auch zwingend eine entsprechende
codecvt-Facette vorhanden ist (der Standard verlangt das).
Wäre es da nicht logisch, von Nutzer eine Facette setzen zu
lassen, wenn er sie benötigt?
Die Lokale eines Streams ist nichts anderes als eine Sammlung von Facetten
(plus ein Referenzzaehler), darueber kommst Du dann an die codecvt-Facette
ran.
Gibt es eine Möglichkeit, die Facette zu nullen,
Nein, es ist ein Implementierungdetail welches der Stream (oder besser der
std::filebuf) selber verwaltet. Eigentlich braucht es nichtmal einen
Pointer zu geben, der std::filebuf kann auch einfach jedesmal in der
Lokalen nachgucken.
so daß ein Verhalten wie mit dem Nichtstandard-FILE-Konstruktor
erreicht werden kann?
....ja, konfiguriere den Stream einfach mit einer Lokalen die die passende
Facette hat.
Weil Streams prinzipiell Zeichenströme, nicht 8 bit Ströme, sind! Wenn
du binäre Daten haben willst, lies in einen char* ein.
Wie, alles ist Text??? Dann ist aber die C++-Library ziemlich
unvollständig, oder wie bekomme ich rein binären IO in Dateien hin? Es
kann ja eigentlich nicht sein, dass ich dafür die CRT benutzen soll?
Wenn Du unformatierten IO machen willst (bzw nur IO den Du vorher bereits
irgendwie formatiert hast) dann nimm besser einen char-basierten
streambuffer (std::filebuf fuer Dateien). Diesem verpasst Du vorher noch
eine passende Lokale (std::locale::classic() - dadurch keine weiteren
Konvertierungen) und falls es ein File ist oeffnest Du ihn mit dem
binary-Flag. Dass die Lokale auch im Streambuffer gesetzt werden muss ist
in der Tat einer der groesseren Kritikpunkte am Design der IOStreams,
eigentlich sollte es wirklich nur ein 'raw IO helper' sein.
Sorry, einige Dinge sind im C++ Standard in der Tat nicht perfekt, aber der
Standard hat immer noch den Vorteil dass man sich auf ihn verlassen kann.
IOStreams insbesondere haben einige Stellen an denen man heute weiter ist
bzw die man anders loesen wuerde, siehe z.B. Boost.IOStream. Ansonsten, das
bereits erwaehnte Buch von Langer und Kreft erklaert wirklich genau wie das
alles zusammenspielt.
hilft nix, is einfach so
Uli
.
- Follow-Ups:
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- References:
- STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- From: Ulrich Eckhardt
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- From: Ulrich Eckhardt
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- From: Ulrich Eckhardt
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- From: Ulrich Eckhardt
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- Re: STL-Streams und Unicode/UTF-16
- From: Christoph Rabel
- Re: STL-Streams und Unicode/UTF-16
- From: Andreas Heyer
- STL-Streams und Unicode/UTF-16
- Prev by Date: Re: Command Line eines Prozesses ermitteln (Win32)
- Next by Date: Re: STL-Streams und Unicode/UTF-16
- Previous by thread: Re: STL-Streams und Unicode/UTF-16
- Next by thread: Re: STL-Streams und Unicode/UTF-16
- Index(es):
Relevant Pages
|