C++ std::ofstream写入\r即使在二进制模式下
我正在尝试使用std::ofstream()编写UTF-16编码文件。即使在二进制模式下写入C++ std::ofstream写入\r即使在二进制模式下,c++,binaryfiles,ofstream,C++,Binaryfiles,Ofstream,我正在尝试使用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 我一定是
“\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
更新:它莫名其妙地开始按预期工作。把它记在机器里的鬼魂身上。这是故意的。\n字符被转换为平台的EOL标记,因此ofstream::write函数可以正确地解释它。如果要编写二进制文件,则不能使用特殊的文本字符 澄清: 我设法对编译器正在做什么产生了一点困惑。基本上,\n是一个特殊字符,表示“下线/行尾”。这取决于编译所使用的平台 现在,write()函数将获取一个字节数组来写入流。C标准并没有真正区分字符串(在C中技术上并没有这样的东西)和字符(或字节)数组,所以它可以让您不受影响。编译期间发生的情况是,这些行被转换为如下内容:
fout.write({255, 254, 0}, 2); // "\xff\xfe"
fout.write({13, 10, 0, 0}, 2); // "\n\0"
fout.close();
您发送了4个字节进行输出。在输出中观察到5个 不知何故,您没有使用二进制模式。没有其他方法可以使用.write(buf,2)和.write(buf,2)获得5字节的输出 很可能,在搞乱/玩弄东西的过程中(就像人们在试图找出奇怪行为的原因时经常做的那样),您更改的某些内容导致它实际断言二进制模式
如果您之前尝试输出到STDOUT或STDERR,则完全可能是windows自动将“\r”添加到流中,因为STDOUT和STDERR几乎都是文本,这可能会覆盖您将其置于二进制模式的尝试。(不,真的。不,您使用的是Visual Studio,这是一个真正的。是的,如果您使用cygwin,这不是真的,但您使用的是VS。)传递
\x0A
(换行符)是否有效?我认为只有\n
有特殊的含义,但我不确定。到CR+LF的新行转换发生在运行时,而不是编译器。它应该只在文本模式下执行,而不是二进制模式。使用<代码> fUT.Script(“\x0a”,1)< /C> >具有相同的效果。在C或C++标准中,编译器在字符串或字符文本中解释或转换<代码> \n <代码> > <代码> \n r r/COD>。库可能会对文本模式文件执行此操作,但这与编译器将字符解释为它们不是的东西大不相同。“如果要编写二进制文件,不能使用特殊的文本字符。”-它们以二进制模式编写,因此不应进行翻译。根据代码和问题,你的答案仍然是错误的。“如果你想写一个二进制文件,你不能使用特殊的文本字符。”-这完全是错误的。如果你不能写某些字符,你还怎么写二进制文件呢?“编译时发生的事情”-不,它不是在编译时发生的。即使在运行时发生转换,也只有在以文本模式而不是二进制模式打开流时才会发生。在二进制模式下不应进行转换。如果有翻译,那么某处就有错误。关于fout.write(“\x0a\0”,2)代码>?这会起作用,但OP的做法是错误的。这条路只会带来更多的痛苦和痛苦,Unicode也会陷入困境。“\x0a”
也有同样的效果。Jesse,出于其他原因,我需要这样做,但问题的要点是\r不应以二进制模式写入。将字节写入流,而不是文本。使用如下内容:char[]buffer={255,254,0,10};四次写入(缓冲器,4);