13

I am trying to understand how the fread() function in <stdio.h> works and I am confused about the return value of this function. In the man pages it says

RETURN VALUE
On success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1. If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).

fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.

Could someone please explain to me what is meant by number of items read or written in this context. Also can anyone provide me with some example return values and their meanings?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jordan Camp
  • 842
  • 4
  • 9
  • 20
  • 3
    `fread()` reads `N * K` bytes, where `N` is the number of bytes in each element, and in total `K` elements will be read. Ideally, if no error occurs, `K` will be returned. If an error or end-of-file condition occurs, then less than `K` elements may be read, in which case a number smaller than `K` will be returned. – The Paramagnetic Croissant Feb 08 '15 at 19:24
  • Related: http://stackoverflow.com/q/8589425/827263 – Keith Thompson Feb 08 '15 at 20:30

2 Answers2

18

fread() will read a count of items of a specified size from the provided IO stream (FILE* stream). It returns the number of items successfully read from the stream. If it returns a number less than the requested number of items, the IO stream can be considered empty (or otherwise broken).

The number of bytes read will be equal to the number of items successfully read times the provided size of the items.

Consider the following program.

#include <stdio.h>

int main() {
    char buf[8];
    size_t ret = fread(buf, sizeof(*buf), sizeof(buf)/sizeof(*buf), stdin);
    printf("read %zu bytes\n", ret*sizeof(*buf));
    return 0;
}

When we run this program, depending on the amount of input provided, different outcomes can be observed.

We can provide no input at all. The IO stream will be empty to begin with (EOF). The return value will be zero. No items have been read. Zero is returned.

$ : | ./a.out
read 0 bytes

We provide fewer input as requested. Some items will be read before EOF is encountered. The number of items read is returned. No more items are available. Thereafter the stream is empty.

$ echo "Hello" | ./a.out
read 6 bytes

We provide equal or more input as requested. The number of items as requested will be returned. More items may be available.

$ echo "Hello World" | ./a.out
read 8 bytes

Related reading:

When there are less bytes in the stream than consitute an item, the number of bytes consumed from the stream might however be greater than the number of bytes read as calculated by above formula. This answer to above linked question (and the comment to it) I find especially insightful in this matter:

Community
  • 1
  • 1
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • Your program would be more helpful (regarding the question) if it did a fread() of a file being 7 bytes long and the size set to 1, 2 and 4. – ott-- Feb 08 '15 at 19:59
7

The syntax for fread() is

size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream );

which means,

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

So, the total number of bytes read will be nmemb * size.

Now, by saying

on success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1.

it means that, the return value will equal the nmemb when the size is 1.

Logic is same, in case of fwrite() also.


EDIT

for example, a fully successful call to fread() like

 fread(readbuf, sizeof(int), 5 , stdin);

will return 5 while it will read sizeof(int) * 5 bytes. If we assume sizeof(int) is 4, then total bytes read will be 5 * 4 or 20. As you can see, here, the number of items read or written is not equal to the number of bytes transferred.

OTOH, another fully successful call to fread() like

fread(readbuf, sizeof(char), 5 , stdin);

will also return 5 while it will read sizeof(char) * 5 bytes, i.e., 5 bytes. In this case, as sizeof(char) is 1, so, here, the number of items read or written is equal to the number of bytes transferred. i.e., 5.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • what happens when size != 1 though? I'm reading through code that passes the size of a struct to this function. – Jordan Camp Feb 08 '15 at 19:33