给定特定的字节格式,如何通过fread读取结构?

时间:2013-09-26 23:20:58

标签: c struct

我在从二进制文件读取给定特定格式的结构时遇到问题。同样,给定一个字节的定义(偏移量:0长度:2值:0xFF 0xD8,偏移量:2长度:2值:0xFF 0xE1等),我不知道如何定义我的结构也不利用文件像fread()这样的操作;正确地接收我正在寻找的信息。

目前,我的结构如下:

struct header{
    char start; //0xFF 0xD8 required.
    char app1_marker; //0xFF 0xE1 required. Make sure app0 marker (0xFF 0xE0) isn't before.
    char size_of_app1_block; //big endian
    char exif_string; //"EXIF" required
    char NULL_bytes; //0x00 0x00 required
    char endianness; //II or MM (if not II break file)
    char version_number; //42 constant
    char offset; //4 blank bytes
};

struct tag{
    char tag_identifier;
    char data_type;
    char size_of_data;
    char data;
};

如果结构的每个属性具有不同的(奇数)字节长度,我应该使用哪些数据类型?有些需要2个字节的空间,有些需要4个,甚至其他的是可变/动态长度。我正在考虑使用char数组,因为char总是C中的一个字节。这是个好主意吗?

另外,如果我试图立即读取整个结构,那么使用fread的正确方法是什么?我会把它留在:

fread(&struct_type, sizeof(char), num_of_bytes, FILE*);

任何帮助我走过这堵墙的指导都会非常感激。我已经理解了基本的结构上的错误和结构,我遇到的两个关键问题是信息的方差和奇数字节大小以及在一个fread语句中将变量字节大小读入结构的正确方法。

这是项目链接: http://people.cs.pitt.edu/~jmisurda/teaching/cs449/2141/cs0449-2141-project1.htm

1 个答案:

答案 0 :(得分:2)

我通常会在结构上看到fread()指定大小作为结构大小,元素数量指定为1,以及期望fread()返回1:

size_t result = fread(&record, num_of_bytes, 1, infile);

我不确定您如何确定endianess字段是II还是MM,但我想这是您可以决定是否修复字段值根据文件endianess是否与主机endianess匹配。

实际数据似乎是tag结构,最后一个字段data实际上只是size_of_data字段中指定的可变长度数据的占位符。所以我猜你会先读sizeof(struct tag) - 1个字节,然后再读size_of_data个字节。

struct tag taghdr;
size_t result = fread(&taghdr, sizeof(taghdr) - 1, 1, infile);
if (result != 1) { /* ...handle error */ }
struct tag *tagdata = malloc(sizeof(taghdr) + taghdr.size_of_data - 1);
if (tagdata == 0) { /*...no more memory */ }
memcpy(tagdata, &taghdr, sizeof(taghdr) - 1);
if (taghdr.size_of_data > 0) {
    result = fread(&tagdata->data, taghdr.size_of_data, 1, infile);
    if (result != 1) { /*...handle error */ }
}