读取二进制文件时如何分别对每个结构字段使用 fread()?
How to use fread() for each struct field separately when reading binary file?
在我的struct
中我有字段
struct records {
short link;
double gate;
unsigned char bar;
int rest;
char rink;
};
在我的 main()
int main(int argc, char* argv[]){
struct records rec;
if(argc<2){//no paramaters
//return error
}
FILE *fp=fopen(argv[1], "rb");
if(fp==NULL){//no file
//return error
}
//use fread() for each field in struct separately.
fclose(fp);
return 0;
}
如何调用 fread()
以便它分别读取每个 struct
字段,然后将它们打印出来?我知道(每个类似的在线问题和 tut)显示通过提供整个 struct
来调用 fread()
,但我不想这样做,例如。 fread(&rec, sizeof(rec), 1, fp)
。我想用自己的 fread()
调用分别读取每个字段。感谢任何帮助,谢谢。
fread 需要两个重要参数:指针和长度。
您可以轻松获得两者:
struct records {
short link;
double gate;
unsigned char bar;
int rest;
char rink;
};
int main(int argc, char* argv[]){
struct records rec;
// ...
FILE *fp=fopen(argv[1], "rb");
// ...
//use fread() for each field in struct separately.
while (!feof(fp))
{
if (fread(&rec.link, sizeof(rec.link), 1, fp) != 1
|| fread(&rec.gate, sizeof(rec.gate), 1, fp) != 1
|| // etc...
)
{
// error !
}
// print the contents of rec, for example...
}
// ...
}
我来晚了,但这可能有用。
您可以在 offsetof()
函数的帮助下完成此操作。
这里涉及填充字节。
sizeof(struct records)
在我的机器中是 32
字节(但不同机器可能不同)。
然而 struct record
变量的所有成员的组合大小仅为
sizeof(short)+sizeof(double)+sizeof(unsigned char)+sizeof(int)+sizeof(char)
在我的机器上应该是 16
字节(假设 short
, double
, unsigned char
, int
& char
占用 2 , 8, 1, 4 & 1 字节)。
这是因为所谓的填充字节。您可以阅读此 here。这样做是为了让处理器更轻松。
所以根据这些尺寸,
一个struct record
就像
----------------------------------------------------------------
| link(2) | 6 bytes |
----------------------------------------------------------------
| gate (8) |
----------------------------------------------------------------
| bar(1) | 3 bytes | rest(4) |
----------------------------------------------------------------
| rink(1) | 7 bytes |
----------------------------------------------------------------
首先找到struct
的每个成员开始的点
printf("link: %d\n", offsetof(struct records, link));
printf("gate: %d\n", offsetof(struct records, gate));
printf("bar: %d\n", offsetof(struct records, bar));
printf("rest: %d\n", offsetof(struct records, rest));
printf("rink: %d\n", offsetof(struct records, rink));
这会打印
link: 0
gate: 8
bar: 16
rest: 20
rink: 24
您可以使用此方法来查找结构成员在您的机器中是如何打包的。
您现在需要做的是在忽略填充字节的情况下读取所需的数据。
让我们创建一个结构变量a
。
fread(&a.link, sizeof(a.link), 1, fp);
fseek(fp, 6, 1); //move the file pointer by 6 bytes from current position to avoid the padding bytes
fread(&a.gate, sizeof(a.gate), 1, fp);
fread(&a.bar, sizeof(a.bar), 1, fp);
fseek(fp, 3, 1); //move the file pointer to avoid the 3 bytes
fread(&a.rest, sizeof(a.rest), 1, fp);
fread(&a.rink, sizeof(a.rink), 1, fp);
现在您可以使用 a
中的值。
当你问上一个问题时,我不知道该怎么做。但是我做了一些阅读并找到了一种方法。由于您 post 提出了一个单独的问题,我认为最好在此处 post 回答。
在我的struct
中我有字段
struct records {
short link;
double gate;
unsigned char bar;
int rest;
char rink;
};
在我的 main()
int main(int argc, char* argv[]){
struct records rec;
if(argc<2){//no paramaters
//return error
}
FILE *fp=fopen(argv[1], "rb");
if(fp==NULL){//no file
//return error
}
//use fread() for each field in struct separately.
fclose(fp);
return 0;
}
如何调用 fread()
以便它分别读取每个 struct
字段,然后将它们打印出来?我知道(每个类似的在线问题和 tut)显示通过提供整个 struct
来调用 fread()
,但我不想这样做,例如。 fread(&rec, sizeof(rec), 1, fp)
。我想用自己的 fread()
调用分别读取每个字段。感谢任何帮助,谢谢。
fread 需要两个重要参数:指针和长度。
您可以轻松获得两者:
struct records {
short link;
double gate;
unsigned char bar;
int rest;
char rink;
};
int main(int argc, char* argv[]){
struct records rec;
// ...
FILE *fp=fopen(argv[1], "rb");
// ...
//use fread() for each field in struct separately.
while (!feof(fp))
{
if (fread(&rec.link, sizeof(rec.link), 1, fp) != 1
|| fread(&rec.gate, sizeof(rec.gate), 1, fp) != 1
|| // etc...
)
{
// error !
}
// print the contents of rec, for example...
}
// ...
}
我来晚了,但这可能有用。
您可以在 offsetof()
函数的帮助下完成此操作。
这里涉及填充字节。
sizeof(struct records)
在我的机器中是 32
字节(但不同机器可能不同)。
然而 struct record
变量的所有成员的组合大小仅为
sizeof(short)+sizeof(double)+sizeof(unsigned char)+sizeof(int)+sizeof(char)
在我的机器上应该是 16
字节(假设 short
, double
, unsigned char
, int
& char
占用 2 , 8, 1, 4 & 1 字节)。
这是因为所谓的填充字节。您可以阅读此 here。这样做是为了让处理器更轻松。
所以根据这些尺寸,
一个struct record
就像
---------------------------------------------------------------- | link(2) | 6 bytes | ---------------------------------------------------------------- | gate (8) | ---------------------------------------------------------------- | bar(1) | 3 bytes | rest(4) | ---------------------------------------------------------------- | rink(1) | 7 bytes | ----------------------------------------------------------------
首先找到struct
的每个成员开始的点
printf("link: %d\n", offsetof(struct records, link));
printf("gate: %d\n", offsetof(struct records, gate));
printf("bar: %d\n", offsetof(struct records, bar));
printf("rest: %d\n", offsetof(struct records, rest));
printf("rink: %d\n", offsetof(struct records, rink));
这会打印
link: 0
gate: 8
bar: 16
rest: 20
rink: 24
您可以使用此方法来查找结构成员在您的机器中是如何打包的。
您现在需要做的是在忽略填充字节的情况下读取所需的数据。
让我们创建一个结构变量a
。
fread(&a.link, sizeof(a.link), 1, fp);
fseek(fp, 6, 1); //move the file pointer by 6 bytes from current position to avoid the padding bytes
fread(&a.gate, sizeof(a.gate), 1, fp);
fread(&a.bar, sizeof(a.bar), 1, fp);
fseek(fp, 3, 1); //move the file pointer to avoid the 3 bytes
fread(&a.rest, sizeof(a.rest), 1, fp);
fread(&a.rink, sizeof(a.rink), 1, fp);
现在您可以使用 a
中的值。
当你问上一个问题时,我不知道该怎么做。但是我做了一些阅读并找到了一种方法。由于您 post 提出了一个单独的问题,我认为最好在此处 post 回答。