【问题标题】:Weird error when using fread with struct将 fread 与 struct 一起使用时出现奇怪的错误
【发布时间】:2015-05-19 05:26:27
【问题描述】:

所以,我尝试使用 fread 和结构读取 BMP 图像。我创建以下结构来读取标题

struct head{
char sigBM[2];//This will get the 'B' and 'M' chars
int fileSize;
int reserved;
int offset
...
};

在我使用的主要功能中

fread(pointerToStruct,sizeof(struct head),1,image);

我刚刚得到了一些奇怪的结果。但后来我决定从结构中取出 char sigBM[2] 并用不同的 fread 读取它。比如:

char sigBM[2];
struct head *p = malloc(sizeof(struct head));/*
Without the char sigBM[2]
*/
fread(sigBM,sizeof(char),2,image);
fread(p,sizeof(struct head),1,image);

它成功了!

我已经开始工作了,我只是想知道为什么会这样

【问题讨论】:

  • struct head 可能有一些填充:sigBMfileSize 之间的两个未使用的字节,仍然占用空间,因此消耗了您在读取时未预料到的两个字节。你可以告诉你的编译器不要填充这个结构;不过,我没有这方面的经验。
  • 确保sizeof(struct head) 与您代码中的sizeof(struct head) 文件相同。

标签: c fread bmp


【解决方案1】:
the OP has workable idea.  It does need some extension.

Of some note is that several fields within the .bmp file
have non-fixed offsets from the start of the file.
so a single struct will not properly handle the whole file

Of critical interest is the number of 'special' color entries
as that changes the offsets for all the rest of the file.

the actual image, depending on the pixel width and the image width
can have from 0 to 3 bytes of filler for each pixel line of the image

certain fields are optional in the second section of the file.
and some fields within the first section of the file contain 
offsets into the file for other key areas.

in general, it is best to treat the file as a long string of bytes
and use offsets (and field length) to access specific fields 

this has been demonstrated, with full C code, 
on several answers in stackoverflow.com

suggest performing a search.

【讨论】:

    【解决方案2】:

    在 16 位 int、32 位 long 世界中

    struct head{
      char sigBM[2];
      long fileSize;
      long reserved;
      long offset
      ...
    };
    

    一切正常。但是尝试使用具有填充(字段之间的额外空间)的结构读取会导致 OP 的问题。

    一种解决方案是读取每个字段,一次一个 - 就像 OP 的方法一样。另一种方法是使用编译器特定的选项或关键字来“打包”结构。


    一般来说,给定 C 变体 int 的大小,最好将这些字段视为 int8_tint16_tint32_t 而不是 charint 等。

    【讨论】:

      【解决方案3】:

      您的数据似乎在没有填充的情况下写入磁盘。那是;整数fileSize 直接出现在两个字符之后。这通常不是结构在内存中的保存方式。

      大小

      struct head{
        char sigBM[2];//This will get the 'B' and 'M' chars
        // two padding bytes hide here
        int fileSize;
      }
      

      在我的机器上是 8。不是您所期望的 2+4。如果您在同一平台上使用相同的编译器选项读/写,则可以预期该结构被正确读入。如果没有,您需要控制这些细节。

      大多数架构要求(或更喜欢)数字类型以 2 的特定乘数开始 [例如类型本身的大小]。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-21
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        • 2020-08-30
        • 2013-05-05
        相关资源
        最近更新 更多