Seite 1 von 1

(gelöst) wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 14:02
von Krishty
Hi,

Ich möchte ::std::wcout in eine Datei umleiten … dazu lege ich einen ::std::wfstream an und binde ihn per rdbuf().
Das Ganze klappt – allerdings nur, solange keine Buchstaben > 255 geschrieben werden. Ich finde es irgendwie komisch, dass wcout und wfstream keine wchars akzeptieren?!?

Ist das Verhalten beabsichtigt? (VS 2010 RC)

Gruß, Ky

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 14:47
von Helmut
Ist bei mir (VS05) genauso. Ich vermute mal, dass das ein alter Bug ist, der wegen Abwärtskompatibilität nicht mehr gefixt werden kann.
Als Workaround hab ich einfach die Ansivariante benutzt und Unicodestrings mit der write Methode geschrieben. Ansonsten wäre vielleicht auch fopen eine Alternative, die nicht so schlecht ist, wie viele denken ;)

Ciao

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 15:19
von Krishty
Helmut hat geschrieben:Ich vermute mal, dass das ein alter Bug ist, der wegen Abwärtskompatibilität nicht mehr gefixt werden kann.
Dachte ich auch, denn als ich das verfolgt habe ist er in einem Template hängengeblieben, das zwar mit wchar_t instantiiert war, intern aber ::std::string benutzt hat. Verstreute Google-Ergebnisse wollen mir aber erzählen, dass das normal ist und man ein passendes Locale einstellen muss? Kann nicht sein, da arbeitet doch die Typsicherheit entgegen? Wenn ich die Datei binär öffne schreibt er nicht einmal Zeilenumbrüche, versucht aber trotzdem, zu konvertieren? Ich überreiße momentan nichts.
Helmut hat geschrieben:Als Workaround hab ich einfach die Ansivariante benutzt und Unicodestrings mit der write Methode geschrieben. Ansonsten wäre vielleicht auch fopen eine Alternative, die nicht so schlecht ist, wie viele denken ;)
Nicht möglich … ich habe in den letzten Monaten eine riesige Code-Basis auf den Streams aufgebaut. Bisher habe ich immernur in den Debug-Output gestreamt, für das Release wollte ich es schnell auf Datei-Output umstellen und nun geht nichts mehr.

Tolle Sache, diese Abstraktion … ein Schritt vor, zwei zurück.

Edit: Sieht mir genau wie das hier aus. Wt…

Edit 2: Das schaut sehr gut aus. Direkt mal ausprobieren.

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 17:57
von Biolunar
Wie herrlich. Und wieder jemand, der an simplen Zeichenketten verzweifelt :)
Es haben schon millionen Leute versucht und alle sind gescheitert (ich auch^^). Mein Rat: Konvertiere Strings IMMER nach utf-8 bevor du sie irgendwie serialisieren willst, sonst hast du früher oder später Probleme. Nach eigener Erfahrung kann man sich auf Locales leider nicht verlassen, was die utf-8 Konvertierung angeht.

Folgender Code funktioniert bei mir zwar (gcc 4.4 linux mit de_DE.UTF-8 als Locale), aber warscheinlich in jeder 0815-Windowsumbegung nicht :/

Code: Alles auswählen

std::locale::global(std::locale(""));
std::wofstream file("datei", std::ios_base::trunc);
file.exceptions(std::ios_base::failbit | std::ios_base::badbit);

std::wstring euro(L"\u20AC"); // Euro-Zeichen
file << euro;
Ich verwende selber UTF-8 CPP zum konvertieren, bisher ohne Probleme.

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 19:05
von Krishty
Das ganze String-Geraffel in der Standardbibliothek ist doch wirklich von vorne bis hinten verkorkst … und genauso verkorkst sind MS, dass sie unzählige Übersetzungsfunktionen bereitstellen, aber keine für UTF-8 … und mit den Line-Feeds fange ich garnicht erst an. Danke für UTF-8 CPP, das hat mir heute echt den Popo gerettet!

Inwiefern kann man sich auf Locales nicht verlassen? Ich habe jetzt UTF-8 CPP als Facet eingebunden (oder sowas ähnliches, entschuldige, aber ich habe heute überhaupt das erste Mal von Locales gehört) und es funktioniert soweit – was soll ich sagen, eben so weit, wie ich es für ein paar Tests mit Sonderzeichen erhofft habe.

Und nein, der Code scheitert mit einem Feuerwerk von irgendwelchen Exceptions, wie erwartet -.-

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 21:00
von Psycho
Passend dazu: Gibts da in C++0x Verbesserungen? Hab mal was von direkter UTF-8-Unterstützung gelesen.
Und ist davon eventuell schon was von bei VS 2010 implementiert?

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 22:03
von Krishty
Ja – in C++0x wird es möglich sein, String-Literals direkt in UTF-8 anzulegen. VC 2010 hat in der Richtung aber noch nichts implementiert.

Re: wfstream akzeptiert keine wide-chars

Verfasst: 15.04.2010, 23:20
von Biolunar
Auf Locales sollte man sich nicht verlassen, da nicht sichergestellt ist, dass der Anwender auch ein UTF-8 Locale verwendet bzw. installiert hat. (Mit Locales meine ich hier nicht std::locale sondern die Betriebssystemspezifischen Locales)

Die std::locale's sind quasi nur benannte Container für die facets wie z.B. ctype oder codecvt. Je nachdem was man für ein Locale gewählt hat, arbeiten die facets unterschiedlich. In den Facets geschiet also die ganze Magie. Zum konvertieren zwischen verschiedenen Zeichensätzen wird std::codecvt verwendet, jedoch gibt es im C++ Standard noch keine Spezialisierung davon, die explizit UTF-8 konvertiert. Dieser Missstand wird aber durch C++0x (endlich) behoben :) Daher sind Konvertierungen noch systemabhängig...

Re: wfstream akzeptiert keine wide-chars

Verfasst: 29.03.2011, 14:38
von kaiserludi
Krishty hat geschrieben:und genauso verkorkst sind MS, dass sie unzählige Übersetzungsfunktionen bereitstellen, aber keine für UTF-8
Wie wäre es hiermit:

Code: Alles auswählen

char* Unicode2UTF8(const EG_CHAR* wstr, int src_len, unsigned char* dst, int dst_size)
{
	WideCharToMultiByte(CP_UTF8, 0, wstr, src_len, dst, dst_size, 0, 0);
	return dst;
}

EG_CHAR* UTF82Unicode(const unsigned char* str, int src_size, EG_CHAR* dst, int dst_len)
{
	MultiByteToWideChar(CP_UTF8, 0, str, src_size, dst, dst_len);
	return dst;
}

Re: (gelöst) wfstream akzeptiert keine wide-chars

Verfasst: 29.03.2011, 14:45
von Krishty
Ehrlich gesagt weiß ich nicht mehr, was ich damit meinte … es kann sein, dass ich über das fehlende Locale fluchen wollte. Oder aber, dass ich diese Funktion tatsächlich noch nicht kannte. KA.