我在从二进制文件读取给定特定格式的结构时遇到问题。同样,给定一个字节的定义(偏移量: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
答案 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 */ }
}