2009-05-03 8 views
1

Ich habe gerade einige seltsame Verhalten im Umgang mit dem ominösen typographischen Apostroph (') - nicht der Schreibmaschine Apostroph ('). Bei Verwendung eines breiten Zeichenfolgenliterals bricht der Apostroph den Worstream.Typografische Apostroph + Wide String Literal brach mein wofstream (C++)

Dieser Code funktioniert

ofstream file("test.txt"); 
file << "A’B" ; 
file.close(); 

==> A'B

Dieser Code funktioniert

wofstream file("test.txt"); 
file << "A’B" ; 
file.close(); 

==> A'B

Dieser Code schlägt fehl

wofstream file("test.txt"); 
file << L"A’B" ; 
file.close(); 

==> A

Dieser Code schlägt fehl ...

wstring test = L"A’B"; 
wofstream file("test.txt"); 
file << test ; 
file.close(); 

==> A

Jede Idee?

+0

Inwiefern scheitert es? Ausnahme? – Skurmedel

+0

Die Zeichenfolge ist abgeschnitten. –

Antwort

1

Sie sollten "enable" locale vor der Verwendung wofstream:

std::locale::global(std::locale()); // Enable locale support 
wofstream file("test.txt"); 
file << L"A’B"; 

Also, wenn Sie Systemgebietsschema haben en_US.UTF-8 dann die Datei test.txt wird utf8 codierte Daten (4 byes) umfassen, wenn Sie Systemgebietsschema haben en_US.ISO8859-1, dann würde es als 8-Bit-Codierung (3 Bytes) codieren, es sei denn, ISO 8859-1 verfehlt ein solches Zeichen.

wofstream file("test.txt"); 
file << "A’B" ; 
file.close(); 

Dieser Code funktioniert, weil "A’B" tatsächlich utf-8-String ist und Sie sparen utf-8 String Byte für Byte Datei.

Hinweis: Ich nehme an, Sie verwenden POSIX wie OS, und Sie haben Standardgebietsschema anders als "C", das das Standardgebietsschema ist.

+0

std :: locale :: global (std :: locale ("französisch")); funktioniert. Ich denke, ich verstehe jetzt (oder zu beginnen). Normalerweise, wenn ich mit Unicode-Zeichen (zu vage ... ich weiß) ohne 'L', wird der Compiler (VS) warnen mich mit "Zeichen von Universal-Character-Name dargestellt ... kann nicht in der aktuellen Codepage dargestellt werden ". Dieses Mal war ich überrascht, diese Warnung nicht zu sehen, also nahm ich an, dass etwas nicht stimmte. Auch ich denke/dachte, dass UTF-8 verwendet nur 1-Byte-Codierung für 128 US-ASCII ... –

+0

1st: UTF-8 ist kompatibel mit US-ASCII. Ich weiß eigentlich nicht, wie VS Unicode-Buchstaben darstellt, gcc verwendet standardmäßig utf-8, VS kann lokalen Zeichensatz verwenden. Aber die allgemeine Idee, dass Sie ein Gebietsschema einrichten müssen, das breite Buchstaben in Locale-codierende 8-Bit-Buchstaben umwandelt. Unter Unix ist das normalerweise utf8 – Artyom

0

Sind Sie sicher, dass die Unterstützung für Unicode-Zeichen in Quelldateien durch den Compiler nicht "kaputt" ist? Was ist, wenn Sie \x oder ähnliches verwenden, um das Zeichen im Stringliteral zu codieren? Ist Ihre Quelldatei sogar in welcher Kodierung auch immer ein wchar_t für Ihren Compiler?

+0

Was mich verwirrt ist, dass bei der Verwendung von Unicode (http://mariusbancila.ro/blog/?p=135) wostream und 'richtig funktioniert.Aber warum funktioniert dann auch ohne Unicode? –

+0

"Unicode" ist zu vage. Sie können z.B. UTF-8 mit Ofstream und es ist immer noch Unicode, aber Sie würden nicht wchar_ts verwenden. Auch hier handelt es sich höchstwahrscheinlich um eine Interaktion zwischen der Codierung Ihrer Quelldatei und dem, was Sie tatsächlich in die Zeichenfolgenliterale einfügen, und was Ihr Compiler von Ihrer Quelldatei erwartet/denkt. Der Blogpost verwendet Windows-APIs, verwenden Sie Windows mit VC++? –

0

Versuchen Sie, das Stream-Einfügezeichen in einen try-catch-Block einzubinden, und teilen Sie uns mit, welche Exception ausgelöst wird.

Ich bin mir nicht sicher, was hier vor sich geht, aber ich werde sowieso raten. Das typografische Apostroph hat wahrscheinlich einen Wert, der in ein Byte passt. Dies funktioniert mit "A’B", da es blind Bytes kopiert, ohne sich um die zugrunde liegende Codierung zu kümmern. Mit L"A’B" kommt jedoch ein implementierungsabhängiger Kodierungsfaktor ins Spiel. Es findet wahrscheinlich nicht das richtige UTF-16 (wenn Sie unter Windows sind) oder UTF-32 (wenn Sie auf * nix/Mac sind), um dieses spezielle Zeichen zu speichern.