为什么使用unsigned chars写入二进制文件?为什么不应该使用流操作符来写入二进制文件?

时间:2011-09-18 07:55:51

标签: c++ file input io

我的第一个问题是,为什么习惯使用无符号字符以二进制模式写入文件?在我看到的所有示例中,在写入二进制文件之前,任何其他数值都会转换为unsigned char。

我的第二个问题是,使用流操作符写入二进制文件有什么不好?我听说read()和write()运算符最适合写入二进制文件,但我真的不明白为什么会这样。使用流操作符写入二进制文件对我来说很好,如果我首先将值转换为unsigned char。

float num = 500.5;
ostream file("file.txt", ios::binary);

file << num  // results in gibberish when I try to read the file later
file << (unsigned char)num  // no problems reading the file with stream operators

提前致谢。

3 个答案:

答案 0 :(得分:3)

chars是C / C ++中的最小类型(根据定义,sizeof( char ) == 1)。它是将对象视为字节序列的常用方法。 unsigned用于避免签名的arithmethic妨碍,并且因为它最好代表二进制内容(0到255之间的值)。

要对二进制文件进行操作,流提供readwrite函数。格式化插入和提取功能。它只是偶然地为你工作,例如,如果你输出一个整数&lt;&lt;那么它实际上将输出整数值的文本表示而不是其二进制表示。在您提供的示例中,在输出之前将float转换为unsigned char,实际上将实数值转换为小整数。当你尝试从文件中读取浮点数时会得到什么?

答案 1 :(得分:2)

因为operator<<的所有重载都被称为格式化函数。在写入输出文件之前,他们格式化数据。换句话说,如果要将二进制数据写入文件,则无法使用它们。可以使用无格式函数将二进制数据写入文件 - 那些不格式化数据的函数。

std::ostream提供一个名为write()无格式输出函数,具有以下签名:

ostream& write ( const char* s , streamsize n );

还回答了其他问题:

  

为什么习惯使用无符号字符以二进制模式写入文件?

没有。这是错误的。函数write()接受const char*,而非const unsigned char *

-

在线文档说明了operator<<

  

应用于输出流的此运算符(&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt;它对流通常执行输出操作,涉及某种格式的数据(例如将数值写为字符序列)。

它说的是write()

  

这是未格式化的输出函数,写入的内容不一定是c字符串,因此在数组s中找到的任何空字符都将复制到目标并且不会结束写入过程

答案 2 :(得分:1)

使用unsigned char的原因是它保证为unsigned,这在按位运算方面非常理想 - 在操作二进制数据时可以派上用场。您必须记住,char(也称为普通char)是来自unsigned char的{​​{3}},并且未指定这是有符号还是无符号类型。

最后,流的格式化功能旨在输出/解析文本人类可读数据表示,例如123456789可以< sup> 1 表示为九个字符"123456789",可以容纳9个字节。为了进行比较,可能的二进制表示形式0x75BCD15可以容纳四个字节,这是紧凑的两倍。

你所做的事情成功并不完全出乎意料,因为某些东西是否是二进制文件,只是由你正在做的事情决定。如果您正在将文本写入文件,则稍后检索该文本是正常的。

1 :取决于例如locales,这是格式化函数的另一个特性。