【问题标题】:Why the byte are upside down?为什么字节是颠倒的?
【发布时间】:2012-07-12 07:05:44
【问题描述】:

我对 C 函数 fwrite 有一个“有趣”的问题。我有一个unsigned int 指针,我想将它写入二进制文件,所以我使用了fwrite。但是文件中的字节是颠倒的。考虑到unsigned int 的大小(在我的情况下为4 字节),例如,如果我的数据是FE 45 78 D4 4C E9 EA F1etc,我看到文件内容为D4 78 45 FE F1 EA E9 4C 等。我该如何解决这个问题? 更多信息:当我说字节以错误的顺序写入时,我的意思是我用来读取文件的每个程序都以错误的顺序看到字节,当然会带来读取错误......我不明白为什么只有 fwrite函数使用不同的方式来表示数据... 更多信息: 我试过了

fwrite(myuipointer,4,size,file);

fwrite(myuipointer,1,size*4,file);

同样的结果。 我还尝试使用指向我的数据的无符号字符指针并将其写入,但没有成功...

【问题讨论】:

  • 似乎是字节序问题。向我们展示您的 fwrite 的外观,我们可以帮助您更正这一点
  • 为什么你认为有什么事情需要解决?有什么坏了吗?
  • 尝试读取您的数据并检查是否有任何问题。在那之前我看不到问题。
  • 我不知道我还能说什么……我有我的 unsigned int 指针。如果我打印它们将按预期顺序显示的数据。当我fwrite这些数据时,顺序是倒置的,所有应用程序都以倒置的顺序看到数据,所以一定是fwrite的行为带来了问题......
  • 是的,你得到了颠倒的顺序,它应该可以工作。您的计算机在内部使用这种倒序,而 fwrite 只是将内部格式转储到文件中。如果您使用 fread 将其读回变量中,它将正常工作。

标签: c byte


【解决方案1】:

这是因为您的计算机使用 little endian 存储语义。这意味着数字的 结尾在前。您习惯于看到 big 结尾在前的数字(例如340,000,其中千位列在十位之前。)

如果您的数据永远不会在 big endian 系统(例如旧的 PowerPC Mac)上被读取,那么您可以通过这种方式写出您的数字,然后在同一系统上将它们读回,然后你会得到正确的顺序。

如果您希望在使用不同字节序的系统之间共享此数据,则必须选择一个字节顺序,坚持使用它,并在写入文件时执行与该字节顺序的转换。 (由于您不了解字节序的概念,我怀疑这不会对您起作用。)

【讨论】:

    【解决方案2】:

    其他人在他们的回答中涵盖了字节顺序的概念,这是在 little-endian 计算机上的预期行为。

    但我查看了您的其他一些问题,您似乎正在处理 JPEG 文件,我猜这就是问题所在?

    JPEG 文件需要在不同类型的计算机之间移植,不仅是 little-endian 和 big-endian,还包括 32 位和 64 位等等。因此 JPEG 定义了自己的标准大小和字节顺序,并且(如果不同)您需要将计算机的内部格式转换为 JPEG 格式。如果您只是将内部表示转储到文件中,这就是 fwrite 所做的,那么任何期望正确 JPEG 格式的程序都会失败。

    如果您下载免费 JPEG 程序或库的源代码,例如 libjpeg,您会发现它们不仅使用 fread 和 fwrite,而且具有根据 JPEG 读取和写入每个字节的代码标准。

    【讨论】:

    • 是的,你猜对了,我正在使用 jpeg...但问题不仅在于 jpeg 格式,因为每个程序都以错误的顺序查看文件中的数据...我写入存储在无符号字符数组中的标头标记,一切正常,但是当我写一个无符号整数时,bum,问题......
    • 字符数组没有“字节顺序”,因为字符只是一个接一个地存储,没有其他可能的顺序。但是对于整数(无符号或有符号,短或长或普通),不同类型的计算机使用不同的格式在内部存储它们,fwrite 只会将该内部格式转储到文件中。因此,如果您想要一种在文件中存储整数的可移植方式(JPEG 只是一个示例),您需要确定一种通用格式,并将您的内部表示转换为该格式。
    • 请注意,您在文件中看到的字节顺序并不是真正的“错误”顺序,它只是您的计算机内部使用的顺序。如果您使用 fread 将其读回变量中,它将正常工作。
    【解决方案3】:

    查看小端和大端数字。 “Big-endian”存储的整数首先存储(整数的)最高位,存储“Little-endian”的整数首先存储最低有效位。

    试试http://en.wikipedia.org/wiki/Endianness - 并不是说​​我会依赖维基百科来获取技术文章,但它很简单。

    【讨论】:

      【解决方案4】:

      这称为字节顺序,您应该阅读有关它的维基百科网页(也许更一般地了解计算机体系结构)以更详细地理解它。同时,如果要发出特定的字节模式来表示特定数据,请使用 unsigned char 数组。除了 unsigned char 的情况外,您不能可移植地使用 fwrite 将结构、数组或原始类型写入磁盘文件(至少,您不能期望任何特定的输出模式)。

      【讨论】:

        【解决方案5】:

        这是因为您的计算机使用 little-endian 表示的数据。这意味着整数等数据从最低有效字节开始存储在内存中。
        您的号码是:

        FE 45 78 D4
        4C E9 EA F1
        

        将从最低有效字节开始表示:

        D4 78 45 FE
        F1 EA E9 4C
        

        在使用数据的大端表示的系统中读取此数据时应小心,但如果您是唯一使用您的应用程序的人,或者您可以确定它只会用于小端系统,您不必担心。

        P.S.:如果您在汇编中需要获取整数的最后两个字节(例如),这也可能是一个问题,您需要确切地知道机器如何表示数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-20
          • 2012-05-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多