我正在尝试使用std :: ofstream()编写UTF-16编码文件。即使在二进制模式下,写入"\n\0"
也会写为"\r\n\0"
。示例代码:
std::string filename = ...
std::ofstream fout(filename, std::ios_base::binary);
fout.write("\xff\xfe", 2);
fout.write("\n\0", 2);
fout.close();
生成的文件的十六进制数据为:
ff fe 0d 0a 00
我一定是做错了。有什么想法阻止写入0x0d吗?
我正在使用MS VisualStudio 2013。
更新:它莫名其妙地开始按预期工作了。把它归咎于机器中的幽灵。
答案 0 :(得分:1)
您发送了4个字节进行输出。在输出中观察到5个。
你不知何故不使用二进制模式。没有其他方法可以使用.write(buf,2)和.write(buf,2)并获得5个字节的输出。
可能,在弄乱/玩弄事物时(正如人们总是在试图弄清楚为什么会出现奇怪的行为时),你改变的东西导致它实际上断言二进制模式。
如果您之前尝试输出STDOUT或STDERR,那么Windows完全可能会自动添加' \ r'因为STDOUT和STDERR几乎总是文本,所以这可能已经覆盖了你将其置于二进制模式的尝试。 (不,真的。不,你正在使用Visual Studio,这是真的。是的,如果你使用cygwin这不是真的,但是你正在使用VS.)
答案 1 :(得分:-4)
这是设计的。 \ n字符转换为您平台的EOL标记,因此ofstream :: write函数正确解释它。如果要编写二进制文件,则不能使用特殊文本字符。
澄清: 我设法对编译器正在做的事情产生了一些混乱。基本上,\ n是一个特殊字符,意思是" EOL / End of Line"这取决于您编译的平台。
现在write()函数正在使用一个字节数组来写入流。 C标准并没有真正区分字符串(技术上在C中没有这样的东西)和字符数组(或字节),所以它可以让你逃脱这一点。编译期间发生的事情是这些行转换为如下所示:
fout.write({255, 254, 0}, 2); // "\xff\xfe"
fout.write({13, 10, 0, 0}, 2); // "\n\0"
fout.close();