2010-06-04 6 views
11

Wie schreibe ich eine std :: codecvt Facette? Ich würde gerne solche schreiben, die von UTF-16 nach UTF-8 gehen, die von UTF-16 zur aktuellen Codepage des Systems (Windows, also CP_ACP) und zur OEM-Codepage des Systems (Windows, also CP_OEM) gehen.Wie schreibe ich eine std :: codecvt Facette?

Cross-Plattform ist bevorzugt, aber MSVC unter Windows ist auch in Ordnung. Gibt es irgendwelche Arten von Tutorials oder etwas in dieser Art, wie man diese Klasse richtig benutzt?

+0

Sie könnten in der einen Blick auf [Beispiel nehmen libstdC++ Handbuch] (http://gcc.gnu.org/onlinedocs/libstdc++/manual/codecvt.html). –

+0

Für Locales und Facetten ist das einzige Buch, das ich kenne, http://www.angelikalanger.com/iostreams.html, aber es hat nur ein paar Seiten auf codecvt speziell. –

+3

Ich kann nicht glauben, dass niemand über diese Klasse in der Standardbibliothek zu wissen scheint - besonders, wenn man bedenkt, wie nützlich es sein kann ... –

Antwort

9

Ich habe eine basierend auf iconv geschrieben. Es kann unter Windows oder jedem POSIX-Betriebssystem verwendet werden. (Sie müssen natürlich mit iconv verlinken).

Enjoy

Die Antwort für die "wie" Frage the codecvt reference zu folgen ist. Ich konnte vor zwei Jahren keine besseren Anweisungen im Internet finden.

Wichtige Hinweise

  • theoretisch gibt es keine Notwendigkeit für eine solche Arbeit. codecvt_byname sollte auf jeder Standard-Support-Plattform ausreichen. Aber in Wirklichkeit gibt es einige Compiler, die diese Klasse nicht unterstützen oder schlecht unterstützen. Es gibt auch einen Unterschied in den Schnittstellen von codecvt_byname auf verschiedenen Compilern.
  • Mein Arbeitsbeispiel ist mit dem Statusvorlagenparameter von codecvt implementiert. Verwenden Sie immer den Standard-mbstate-Typ, da dies die einzige Möglichkeit ist, Ihren Codecvt mit Standard-iostream-Klassen zu verwenden.
  • std :: mbstate_t Typ kann nicht als ein Zeiger auf 64-Bit-Plattformen in einer plattformübergreifenden Weise verwendet werden.
  • staatenlos Konvertierungen arbeiten für kurze Strings, aber fehlschlagen, wenn Sie versuchen, einen Datenblock größer zu konvertieren, die interne Puffergröße streambuf (UTF ist im Wesentlichen Stateful-Codierung)
+1

+1 - Ich wusste nicht, dass 'codecvt_byname' existiert, und es stellt sich heraus, dass mein Compiler tatsächlich so etwas richtig unterstützt. (Wer hätte das gedacht?) Ich akzeptiere das noch nicht, weil es keine direkte Antwort auf die Frage ist, aber wenn/wenn das Kopfgeld abläuft, bekommst du die Punkte trotzdem. –

4

Das Problem mit diesem std :: codecvt ist, dass es eine Lösung ist, die nach einem Problem sucht. Oder vielmehr, das Problem, das es zu lösen versucht, ist unlösbar, also wird jeder, der versucht, es als Lösung zu benutzen, sehr enttäuscht sein.

Wenn Sie nicht wissen, welcher Zeichensatz Ihre Eingabe oder Ausgabe ist, dann wird std :: codecvt Ihnen nie helfen können. Umgekehrt, wenn Sie tun wissen, welche Zeichensätze Sie verwenden, können Sie zwischen ihnen mit einem einzigen Funktionsaufruf trivial konvertieren. Das Umbrechen dieses Funktionsaufrufs in einem komplizierten Durcheinander von Vorlagen ändert diese Grundlagen nicht.

... und deshalb verwendet niemand std :: codecvt. Ich empfehle dir, einfach das zu tun, was alle anderen tun, und so zu tun, als wäre es nie passiert.

+2

Ich weiß genau, welche Codepage und solche ich verwende. Ich möchte angeben können, welche Codepage für iostreams verwendet werden soll. Und das ist nur mit 'std :: codecvt' möglich. Klar, ich kann einen Textblock problemlos zwischen Codepages konvertieren, aber es gibt keine Möglichkeit zu sagen: "Formatiere diese Ganzzahl auf 8 Leerzeichen, fülle die Leerzeichen mit Nullen" ohne ein großes Chaos von "std :: wstringstream" s.Ich würde eher in der Lage sein, iostreams nativ auf die richtige Codepage umzustellen, da es dafür bereits eine Möglichkeit gibt. -1 um die Frage nicht zu beantworten. –

+4

Wie "Niemand verwendet' std :: codecvt' ", können Sie erklären, warum Konvertierungsfacetten für Unicode in C++ 0x hinzugefügt werden, und http://www.boost.org/doc/libs/1_43_0/libs/ Serialisierung/doc/codecvt.html? –

+2

Wahrscheinlich in der Hoffnung, dass Leute * stard * mit std :: codecvt starten, sobald es nicht mehr nutzlos ist. – apenwarr