(gelöst) wfstream akzeptiert keine wide-chars

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

(gelöst) wfstream akzeptiert keine wide-chars

Beitrag 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
Zuletzt geändert von Krishty am 16.04.2010, 15:50, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: wfstream akzeptiert keine wide-chars

Beitrag 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
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: wfstream akzeptiert keine wide-chars

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: wfstream akzeptiert keine wide-chars

Beitrag 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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: wfstream akzeptiert keine wide-chars

Beitrag 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 -.-
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: wfstream akzeptiert keine wide-chars

Beitrag 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?
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: wfstream akzeptiert keine wide-chars

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: wfstream akzeptiert keine wide-chars

Beitrag 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...
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: wfstream akzeptiert keine wide-chars

Beitrag 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;
}
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten