c++ Falscher CRLF im UTF-16-Stream?



visual-c++ unicode (1)

Wenn Sie ein neues Gebietsschema in std::wofstream , std::wofstream Sie das ursprüngliche Gebietsschema. Verwenden Sie nicht locale::empty() , su.getloc() verwenden su.getloc() stattdessen su.getloc() , damit das neue Gebietsschema das alte Gebietsschema kopiert, bevor es su.getloc() .

Außerdem ist der letzte Template-Parameter von codecvt_utf16 eine Bitmaske, also sollte codecvt_mode(generate_header + little_endian) eigentlich std::generate_header | std::little_endian std::generate_header | std::little_endian stattdessen.

su.imbue(std::locale(su.getloc(), new codecvt_utf16<wchar_t, 0x10ffffUL, 
                            std::generate_header | std::little_endian>));

Hier ist ein Problem, das ich trotz all meiner Bemühungen nicht lösen konnte. Also bin ich total fest, bitte helft!

Für den normalen "ASCII" -Modus die folgenden vereinfachten Datei- und Stream-Ausgaben

FILE *fa = fopen("utfOutFA.txt", "w");
fprintf(fa, "Line1\nLine2");
fclose(fa);
ofstream sa("utfOutSA.txt");
sa << "Line1\nLine2";
sa.close();

Ergebnis natürlich in genau den gleichen Textdateien (hex dump):

00000000h: 4C 69 6E 65 31 0D 0A 4C 69 6E 65 32             ; Line1..Line2

wo die neue Zeile \n zu CRLF erweitert wird: 0D 0A - typisch für Windows.

Nun machen wir dasselbe für die Unicode-Ausgabe, nämlich UTF-16 LE, was eine Art "Standard" ist. Dateiausgabe

FILE *fu = fopen("utfOutFU.txt", "w, ccs=UNICODE");
fwprintf(fu, L"Line1\nLine2");
fclose(fu);

Ergebnisse in diesem Inhalt:

00000000h: FF FE 4C 00 69 00 6E 00 65 00 31 00 0D 00 0A 00 ; ÿþL.i.n.e.1.....
00000010h: 4C 00 69 00 6E 00 65 00 32 00                   ; L.i.n.e.2.

was unter Berücksichtigung von BOM und Endianz, einschließlich CRLF: 0D 00 0A 00 vollkommen korrekt aussieht. Allerdings ist die Ausgabe ähnlich

wofstream su("utfOutSU.txt");
su.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffffUL, 
                            codecvt_mode(generate_header + little_endian)>));
su << L"Line1\nLine2";
su.close();

ergibt ein Byte weniger und insgesamt falsche Textdatei:

00000000h: FF FE 4C 00 69 00 6E 00 65 00 31 00 0D 0A 00 4C ; ÿþL.i.n.e.1....L
00000010h: 00 69 00 6E 00 65 00 32 00                      ; .i.n.e.2.

Der Grund ist eine falsche Erweiterung von CRLF: 0D 0A 00 . Ist das ein Fehler? Oder habe ich etwas falsch gemacht?

Ich benutze Microsoft Visual Studio Compiler (14.0 und andere). Ich habe versucht, Stream- endl anstelle von \n - das gleiche Ergebnis! Ich habe versucht, su.imbue() zuerst und dann su.open() - alle gleich! Ich habe auch die UTF-8-Ausgabe überprüft ( ccs=UTF-8 für Datei und codecvt_utf8 für Stream) - kein Problem, da CRLF bleibt wie im ASCII-Modus: 0D 0A

Ich freue mich über Ideen und Kommentare zu diesem Thema.





newline