0

I understand its meaning, per the man page, that

   function  fread() reads nmemb elements of data, each size bytes
   long, from the stream pointed to by  stream,  storing  them  at  the
   location given by ptr.

fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr); fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

but I can't understand why the second argument is size of whatever I'm reading in, and every time reads only 1 byte?

Incidentally, what does nmemb stands for?

2 Answers 2

2

I (think) nmemb stands for: "number of members". Quite arguably, though ;)

The point is you're reading data from stream and writing it into ptr (EDIT: actually you don't write data into ptr; you write it into the location in memory that is pointed to by ptr) (a so called "buffer"). But you'll probably get in trouble if the structure that ptr points to is not big enough to handle all the data retrieved by fread.

So, the designers of fread built into it a tool for you, as a user, to prevent buffer overflows: you "allow" it to read in nmemb items, each of size size (total bytes read = nmemb * size) each time it's invoked.

Such total is the value returned by the function, which you're using to validate your reading process.


EDIT:

Every time you invoke the function, it moves a so-called cursor (EDIT: the cursor is often referred to as the "file position indicator".) from the actual position (initially, the beginning) in the stream (for that's what FILE *file actually is) such total number of bytes ahead. That is, until you decide to fclose() such stream, or until the special symbol EOF ("End Of File") is read, which forces fread() to return.

According to it's man page:

If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).

Such return value is useful in order to determine when you've reached the end of the file, and need to move on in your algorithm.


One more hint regarding your actual implementation: if you defined RGBTRIPLE and BITMAPFILEHEADER as integer constants, e.g.:

#define BITMAPFILEHEADER 10
#define RGBTRIPLE 20

You're probably going to get into trouble.

Those "#" statements are delt with by the preprocessor ("pp"): they're called "preprocessor directives". What the pp does is, simply, replace every occurence of RGBTRIPLE with the value 20 before the compilation. Such value is, in fact, a constant integer.

So, when you execute:

sizeof(RGBTRIPLE);

What actually gets executed after the pp replacement is:

sizeof(20);

Since 20 is an int, you'll get back the size of the type int as defined in your system (same as what you do with malloc), so the result is (in most systems):

4

which is probably not what you expect.

If you're in doubt, try printing out the value of:

printf("%d\n", sizeof(RGBTRIPLE));

and see what comes out ;)

HTH!

7
  • and how does fread going to read through my entire file if it only read it once and only one element? Isn't that going to just read in the same data over and over again?
    – RexYuan
    Dec 9, 2014 at 15:47
  • Please see my updated answer @RexYuan , hope it's clearer now
    – abelinux
    Dec 9, 2014 at 16:02
  • 1
    What's a "short item count"?
    – RexYuan
    Dec 9, 2014 at 16:42
  • 1
    Here is the same question answered ;)
    – abelinux
    Dec 9, 2014 at 16:48
  • 1
    Just for the sake of accuracy: 1. you don't write data into ptr, you write it into the location in memory that is pointed to by ptr and 2. the cursor is often referred to as the file position indicator.
    – kzidane
    Dec 9, 2014 at 21:24
2

This is what man page says

The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the loca‐ tion given by ptr.

The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the loca‐ tion given by ptr.

So, fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr); means read 1 time from the stream pointed by inptr the data of size sizeof(BITMAPFILEHEADER) bytes and store it to memory address of the variable bf.

I hope you get how fread(&triple, sizeof(RGBTRIPLE), 1, inptr); works by analogy.

Good Luck.

2
  • But how if that's the case, how can fread be able to read through the whole file? Every time it calls "fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);", it reads 1 element in BITMAPFILEHEADER. Next time it calls the same fread again. How does fread progress through file?
    – RexYuan
    Dec 9, 2014 at 15:34
  • After every call to fread (and other similar functions), the pointer automatically moves to the next location by certain bytes. You can use fseek() if you wish. http://stackoverflow.com/a/8589688/1904186
    – sinister
    Dec 9, 2014 at 15:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .