【问题标题】:fread and endianness confusionfread 和 endianness 混淆
【发布时间】:2020-03-28 13:30:13
【问题描述】:

所以为了提供上下文,我的系统是小端,我正在读取的文件是大端(MIDI 格式,对于那些感兴趣的人)。我应该从文件中读取各种数据,包括无符号整数(8 位、16 位和 32 位)、字符和布尔值。

到目前为止,我知道读取无符号整数将是 fread() 的一个问题,因为我必须将它们从大端转换为小端。我的第一个问题是,虽然对某些人来说可能很愚蠢,但我是否也需要转换字符和布尔值?

我的第二个问题是关于整个文件格式的。由于文件位于不同的字节序系统中,我是否需要从头到尾读取文件(因为 MSB 和 LSB 位置会不同)?还是我需要像往常一样从头到尾读取值,然后将它们转换为小端?

感谢您花时间阅读我的帖子以及我可能收到的任何答案!

【问题讨论】:

  • 这与fread无关。只需将数据读入内存,然后使用uint16_tuint32_t 访问它们。使用ntohlntohs 函数可以轻松地将这些类型从大端字节顺序转换为主机字节顺序。 char 在所有字节顺序中都是相同的。
  • 我将那些无符号整数存储到它们的 uint_t 对应物中。到目前为止,我有两种方法可以交换 16 位数字和 32 位数字的字节顺序。每次我读到一个 uint 时,我都会给他们打电话。这看起来对吗?我不能使用 ntohl 之类的东西。我受图书馆的约束。
  • 在文件中包含 pointer 的值是不正常的。它不太可能指出任何有用的地方。对于布尔值,如果它在文件中占用超过一个字节,那么字节序也将适用。
  • 它是一个布尔型,所以我认为它只占用1个字节。我为混乱道歉。我将某些字符读入 char 指针。
  • 啊,你编辑的指针是不可能的。对于占用 1 字节存储空间的任何类型,字节顺序无关紧要。反转 1 个字节的序列没有任何作用:它仍然是唯一的一个字节。至于整个文件,你不要颠倒顺序,它是定义的。

标签: c endianness fread


【解决方案1】:

字节序仅在一定长度的单词内反转顺序,通常是 2、4 或 8 个字节。如果您正在读取单字节值,例如 char 或 bool,则字节序无效。但是,如果您正在读取任何超过一个字节的值,例如整数,那么字节序很重要。您仍然可以使用fread,因为字节序与文件读取无关,只需确保从大端转换为小端即可。

【讨论】:

  • 您几乎不会在任何地方看到使用中端序。
【解决方案2】:

当您读取不只是字符序列的外部数据时,您会将其读取为字节序列,并从中构造您想要的实际数据。

如果您期望一个有符号的 16 位数字,后跟一个无符号的 8 位数字,然后是一个无符号的 32 位数字,则您编写一个读取两个字节的函数并将它们转换为一个有符号的 16 位数字,一个读取为 1字节并将其作为无符号 8 位数字返回,另一个读取四个字节并将它们转换为 32 位数字返回。使用位移构造 16 位和 32 位数字。

【讨论】:

    猜你喜欢
    • 2016-07-11
    • 2021-04-10
    • 2021-11-06
    • 2011-12-04
    • 2016-01-12
    • 2013-01-02
    • 2018-06-01
    • 2010-12-02
    • 2017-09-17
    相关资源
    最近更新 更多