UTF-16流中的错误CRLF?

lar*_*ona 9 c++ unicode newline visual-c++

尽管付出了很多努力,但这是一个我无法解决的问题.所以我完全陷入困境,请帮忙!

对于常规的"ASCII"模式,以下简化文件和流输出

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

结果,当然,在完全相同的文本文件(十六进制转储):

00000000h: 4C 69 6E 65 31 0D 0A 4C 69 6E 65 32             ; Line1..Line2
Run Code Online (Sandbox Code Playgroud)

新行\n扩展到CRLF的地方:0D 0A- Windows的典型.

现在,我们对Unicode输出执行相同的操作,即UTF-16 LE,这是一种"默认".文件输出

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

得到这个内容:

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.
Run Code Online (Sandbox Code Playgroud)

考虑到BOM和字节顺序,这看起来非常正确,包括CRLF : 0D 00 0A 00. 但是,类似的流输出

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();
Run Code Online (Sandbox Code Playgroud)

结果减少一个字节和整体不正确的文本文件:

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.
Run Code Online (Sandbox Code Playgroud)

原因是CRLF的错误扩展:0D 0A 00.这是一个错误吗?或者我做错了什么?

我使用Microsoft Visual Studio编译器(14.0和其他).我尝试使用流endl而不是\n- 相同的结果!我试图先放su.imbue(),然后su.open()- 一切都一样!我还检查了UTF-8输出(ccs=UTF-8用于文件和codecvt_utf8流) - 没有问题,因为CRLF保持与ASCII模式相同:0D 0A

我很欣赏这个问题的任何想法和意见.

Rem*_*eau 3

当您将imbue()新的语言环境添加到 中时std::wofstream,您正在清除其原始语言环境。不要使用locale::empty()su.getloc()而是使用 ,这样新的语言环境会在修改之前复制旧的语言环境。

另外,顺便说一句, 的最后一个模板参数codecvt_utf16是位掩码,所以codecvt_mode(generate_header + little_endian)实际上应该是std::generate_header | std::little_endian

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