struct book
{
unsigned short size_of_content;
unsigned short price;
unsigned char *content;
};
Assume I have file that contains multiple book
s, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With