FREAD成结构是不正确的数据 [英] fread into struct reads data incorrectly

查看:82
本文介绍了FREAD成结构是不正确的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在C读取位图(.bmp)映像头成结构

I am trying to read a bitmap (.bmp) image header into a struct in c.

typedef unsigned short WORD;
typedef unsigned long DWORD;

typedef struct _BITMAPFILEHEADER {
    WORD Type;
    DWORD Size;
    WORD Reserved1;
    WORD Reserved2;
    DWORD OffBits;
} BITMAPFILEHEADER;

我的code读取位图文件

My code to read the bitmap file

FILE *fp;
BITMAPFILEHEADER header;

fp = fopen(file,"rb");
if (fp == NULL) {
    printf("cannot open file!\n");
    return 1;
}

fread(&header, sizeof(BITMAPFILEHEADER), 1, fp);

printf("Type: %02x\n", header.Type);
printf("Size: %04x\n", header.Size);
printf("Reserved: %02x\n", header.Reserved1);
printf("Reserved: %02x\n", header.Reserved2);
printf("Offset: %04x\n", header.OffBits);

应该等于什么东西:结果
类型: 0x424d 结果
大小: 0x00060436 结果
保留1: 0×00 结果
RESERVED2: 0×00 结果
偏移: 0x00000436 搜索

What everything should equal:
Type: 0x424d
Size: 0x00060436
Reserved1: 0x00
Reserved2: 0x00
Offset: 0x00000436

什么是真正happning(printf的输出):结果
类型: 0x424d 结果
大小: 0x0006 结果
版权所有: 0x002 结果
版权所有: 0x436 结果
偏移: 0x280000 搜索

What is actually happning (printf output):
Type: 0x424d
Size: 0x0006
Reserved: 0x002
Reserved: 0x436
Offset: 0x280000

(我的操作系统是32位的Ubuntu是否有帮助)

(my os is 32-bit ubuntu if that helps)

推荐答案

在阅读这种文件我认为一个好的办法是先读它们作为字节(流 unsigned char型),然后,如果和当需要时,可以根据适当的数据类型的文件的内容除$ p $角部

When reading this kind of files I think a good approach is to first read them as a stream of bytes (unsigned char) and then, if and when needed, to interpret part of the file contents according to the proper data types.

在你的情况,比如,我会定义 BITMAPFILEHEADER 结构是这样的:

In your case, for instance, I would define the BITMAPFILEHEADER struct like this:

typedef struct _BITMAPFILEHEADER {
    unsigned char   Type[ 2 ];
    unsigned int    Size;          // Size of the BMP file in bytes 
    unsigned char   Reserved1[ 2 ];
    unsigned char   Reserved2[ 2 ];
    unsigned int    OffBits;       // Starting address of the pixel array 
} BITMAPFILEHEADER;

然后我会读取头内容为14字节的块,最后,我会去填补 BITMAPFILEHEADER 结构正常。

下面你可以找到一个简单的程序,读取BMP文件的头并打印到屏幕上。

Below you can find a simple program that reads the header of a BMP file and prints it onto the screen.

int main
    (
    )
    {
    // Defines a few variables
    FILE*           fp   =  0;
    unsigned char   h[ 14 ];

    // Opens the BMP file
    fp   =   fopen( "img.bmp", "rb" );

    if ( fp == NULL )
        {
        printf( "Cannot open file\n" );
        return -1;
        }

    // Reads the BMP header (14 bytes)
    fread( h, 14, 1, fp );

    // Prints the header contents
    printf( "Type:     %02x%02x\n", h[ 0 ], h[ 1 ] );
    printf( "Size:     %02x%02x%02x%02x\n", h[ 2 ], h[ 3 ], h[ 4 ], h[ 5 ] );
    printf( "Reserved: %02x%02x\n", h[ 6 ], h[ 7 ] );
    printf( "Reserved: %02x%02x\n", h[ 8 ], h[ 9 ] );
    printf( "Offset:   %02x%02x%02x%02x\n", h[ 10 ], h[ 11 ], h[ 12 ], h[ 13 ] );

    return 0;
    }

注1 - 填充:从BMP文件格式规范,我们知道,头是14字节长而的printf(%D的sizeof(BITMAPFILEHEADER ))将显示一个不同的(大于!)数量由于填充(见注释你的问题)。

NOTE 1 - Padding: From the BMP file format specification, we know that the header is 14-byte long while a printf( "%d", sizeof(BITMAPFILEHEADER) ) will show a different (greater!) number due to padding (see comments to your question).

注2 - 字节序::当分别写2个或4个字节为一个或长或短,你必须要考虑到字节序。这意味着你必须知道价值是如何写入到文件(位图头,他们是用小尾数符号重新presented),以及他们如何通过你的机器(可能在小尾数表示)。治疗

NOTE 2 - Endiannes: When writing 2 or 4 bytes into a short or long respectively, you have to take into account endiannes. This means that you have to know how values are written into the file (as for the Bitmap header, they are represented using little endian notation) and how they are treated by your machine (probably in little endian notation).

这篇关于FREAD成结构是不正确的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆