如何fread()结构?

时间:2014-02-12 07:53:30

标签: c file file-io struct io

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

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

book

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

感谢。

1 个答案:

答案 0 :(得分:7)

让我们看一下你的struct并考虑它有多大。

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

第一项是unsigned short,没问题,sizeof(unsigned short)可能是2,如2字节。同样是下一个。

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

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

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)

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

由于struct中只有两个字段,因此每个字段fread()非常简单。如果你有一个更复杂的结构,使用结构可能是值得的:

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

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

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


您可能不需要担心这一点,但如果文件是在“big-endian”计算机上编写并在“little-endian”计算机上读取,则会出现问题,反之亦然。< / p>

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

如果确实遇到了这个问题,那么解决方案就是标准化。选择一个(little-endian或big-endian)并使用C库函数来确保使用该endian-ness编写和读取数字。例如,写作时htonl()库函数,阅读时ntohl()

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

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