【问题标题】:wofstream writes unnecessary bytewofstream 写入不必要的字节
【发布时间】:2014-05-27 07:47:18
【问题描述】:

我正在尝试使用 wofstream 以 utf-16 格式输出文件,到目前为止成功。但是我有一个问题要写一个新行。正如我在记事本和十六进制编辑器中发现的那样,Windows 上的新行对应于 2 个符号:LineFedd 和 CarrigeReturn(0x000A 和 0x000D)。试图以编程方式重复这一点会导致奇怪的结果。

#include <fstream>
#include <codecvt>
#include <locale>
#define ENDL L"\u000a\u000d"
using namespace std;
int main()
{
locale utf16(locale(), new codecvt_utf16<wchar_t, 0x10ffffUL, little_endian>());//for writing UTF-16
wofstream fout(L"text.txt");
fout.imbue(utf16);
const unsigned short BOM= 0xFEFF;
fout.write((wchar_t*)&BOM, 1);
fout<<L"some text"<<ENDL<<L"more text";
fout.close();
}

ENDL 后面的文字完全乱了套。我用十六进制编辑器找到了原因。 对于 ENDL,它写入 0D 0A 00 0D 00 。也就是说,由于某种原因,它会在换行符之前写入不必要且有害的 0D 字节,这会导致所有后续字节向右移动,从而弄乱 utf-16 编码。

我不明白为什么会发生这种情况以及如何解决它

【问题讨论】:

  • 这似乎是一个错误......
  • VS 2013 为我抛出 this,根据 2.3/2 是正确的(f c-char-sequence、s-char-sequence 之外的通用字符名称的十六进制值, 或字符或字符串文字的 r-char-sequence 对应于控制字符(在 0x00–0x1F 或 0x7F–0x9F 的任一范围内,均包括在内)或基本源字符集中的字符,程序有问题-形成。)。但这不是您的问题所在。
  • 我实际上使用英特尔编译器而不是 MVS,它吞下了它。但仍然用 L"\r\n" 替换 ENDL 定义具有相同的结果。
  • @AndreyPro 看起来你应该提交bug report
  • 我没有微软账户,注册所有我不想使用的服务感到不安

标签: visual-c++ utf-16 wofstream


【解决方案1】:

尝试以二进制模式打开您的文件:

std::wofstream fout(L"text", std::ios_base::binary);

我没有使用 Windows 系统的经验,但操作系统似乎没有用行尾序列替换 newlunes。

另外,我将首先 imbue() 修改的语言环境和 open() 文件:一旦读取了一个字符,调用 imbue() 要么没有效果,要么没有定义的行为(不记得哪个副手)。我认为没有什么可以阻止流在open() 上读取第一个缓冲区。不过,我认为这不是您的实际问题。

【讨论】:

  • 以二进制模式打开会有所帮助。不过我想知道它是否会导致正常文本出现问题
  • 文本与二进制模式的效果正是用行尾序列替换换行符的行为[在某些系统上]。
  • binary 修复了它,尽管 OP 不应该对控制字符使用通用字符名称。它看起来像是 VS2013 的 codecvt_utf16 实现中的一个错误。
  • 好的,如果使用二进制模式没有副作用,我会坚持下去
猜你喜欢
  • 2013-05-22
  • 2016-12-23
  • 2015-08-16
  • 2012-06-03
  • 2020-10-27
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多