如何 fread() 结构? [英] How to fread() structs?

查看:22
本文介绍了如何 fread() 结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

struct book
{
    unsigned short  size_of_content;
    unsigned short  price;
    unsigned char  *content;
};

假设我有包含多个 book 的文件,每个文件都有不同的 size_of_contentpricecontent.我怎样才能一次读一本 book 并确定它是哪本书(例如检查价格)?

Assume I have file that contains multiple books, each has different size_of_content, price and content. How can I read them one book at a time and identify which book it is (check price, for example)?

size_t nread2;
struct book *buff = malloc(sizeof(struct book));
while( (nread2 = fread(buff, sizeof(struct book), 1, infp)) > 0 )
{
    printf("read a struct once 
");
}

这是我目前所拥有的.每当我阅读结构时,我都会尝试打印.但是,当我尝试使用 5 个结构的输入文件时,它会打印 15 次...

This is what I have so far. I tried to print whenever I read a struct. However, when I tried a input file with 5 structs, it will print 15 times...

谢谢.

推荐答案

让我们看看你的 struct 并想想它有多大.

Let's look at your struct and think about how big it is.

struct book {
    unsigned short  size_of_content;
    unsigned short  price;
    unsigned char  *content;
};

第一项是一个 unsigned short,没问题,sizeof(unsigned short) 可能是 2,就像 2 个字节一样.下一个也一样.

The first item is an unsigned short, no problem, sizeof(unsigned short) probably will be 2, as in 2 bytes. Likewise the next one.

但是第三个.那是一个指向 unsigned char 的指针……你的磁盘记录不可能是保存的指针.您有一个字段 size_of_content...我的猜测是磁盘记录包含 size_of_content,然后是 price,然后是实际内容.

But that third one. That's a pointer to unsigned char... your disk records are not likely saved pointers. You have a field size_of_content... my guess is that the disk records contain the size_of_content, then the price, and then the actual content.

我不会为你写完整的代码,但在伪代码中它是这样的:

I won't write the complete code for you, but in pseudocode it goes something like this:

fread(&size_of_content, sizeof(size_of_content), 1, infp)
sanity-check the value of size_of_content and handle any error
fread(&price, sizeof(price), 1, infp)
sanity-check teh value of price and handle any error
buff->content = malloc(size_of_content)
check for error on malloc and handle any error
fread(buff->content, size_of_content, 1, infp)

如果你没有关于内容有多大的硬性规范,假设它不能超过十亿或类似的东西,并确保这个数字至少不是这么大!始终检查错误.

If you don't have a hard-and-fast spec for how big the content can be, just assume it can't be more than a billion or something like that, and make sure the number at least isn't that huge! Always check for errors.

由于 struct 中只有两个字段,因此只需 fread() 每个字段都非常容易.如果您有一个更复杂的结构,那么使用结构体可能是值得的:

Since there are only two fields in the struct, it's pretty easy to just fread() each one. If you had a more complex structure, it might be worth it to use a struct:

struct book_header {
    unsigned short  size_of_content;
    unsigned short  price;
};

struct book {
    struct book_header header;
    unsigned char *content;
}

然后您可以使用 fread()sizeof(book_header) 一次性读取整个标题.在处理波形音频文件等二进制文件时,我已经编写了很多这样的代码.

Then you can use fread() with sizeof(book_header) to read the whole header in one go. I've written a lot of code like this when working with binary files like wave audio files.

您可能不需要担心这一点,但是如果文件是在大端"计算机上写入并在小端"计算机上读取,反之亦然,这将是一个问题.

You probably don't need to worry about this, but it would be a problem if the file was written on a "big-endian" computer and read on a "little-endian" computer, or vice-versa.

http://en.wikipedia.org/wiki/Endianness

如果您确实遇到了这个问题,那么解决方案就是标准化.选择其中一个(小端或大端)并使用 C 库函数来确保使用该端序写入和读取数字.比如写时的htonl()库函数,读时的ntohl().

If you did have that problem, the solution is to standardize. Pick either one (little-endian or big-endian) and use a C library function to make sure the numbers are written and read using that endian-ness. For example, the htonl() library function when writing, and ntohl() when reading.

http://linux.die.net/man/3/htonl

但正如我所说,你可能不需要担心这个.

But as I said, you probably don't need to worry about this.

这篇关于如何 fread() 结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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