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

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

问题描述

  struct book 
{
unsigned short size_of_content;
未签名的空头价格;
unsigned char * content;
};

假设我有一个包含多个 book 每个都有不同的 size_of_content price content 。我怎么能一次读一本 book ,并确定它是哪本书(例如检查价格)?

  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次...

谢谢。

struct 并考虑它有多大。

  struct book {
unsigned short size_of_content;
未签名的空头价格;
unsigned char * content;
};

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



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

我不会为你写完整的代码,但是在伪代码中,像这样:
$ b $ pre $ code fread(& size_of_content,sizeof(size_of_content),1,infp)
sanity-check价值size_of_content并处理任何错误
fread(& price,sizeof(price),1,infp)
理智检查价格的价值并处理任何错误
buff->内容= malloc(size_of_content)
检查malloc错误并处理任何错误
fread(buff-> content,size_of_content,1,infp)

如果你没有硬性规定内容的大小,只要假设它不能超过十亿或类似的东西那么,确保这个数字至少不是那么大!总是检查错误。

由于 struct 中只有两个字段,所以<$ code> fread()每一个。如果你有一个更复杂的结构,可能值得使用一个struct:

  struct book_header {
unsigned短的size_of_content;
未签名的空头价格;
};

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

$ / code>

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






不必担心这个问题,但如果这个文件是写在big-endian计算机上的,而且是在little-endian的计算机上阅读,反之亦然,那将会是一个问题。

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



如果确实有这个问题,解决方法是标准化。选择一个(little-endian或big-endian),并使用C库函数来确保使用该endian-ness写入和读取数字。例如,在写入时, htonl()库函数,读取时 ntohl()。 b
$ b

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



但是正如我所说的,您可能不需要担心这一点。


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

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 \n");
}

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...

Thanks.

解决方案

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;
};

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

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.

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;
}

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

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天全站免登陆