Jordan Camp
Jordan Camp

Reputation: 872

fread() return value in C

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?

Upvotes: 13

Views: 66768

Answers (2)

Sourav Ghosh
Sourav Ghosh

Reputation: 134396

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.

Upvotes: 7

moooeeeep
moooeeeep

Reputation: 32542

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:

Upvotes: 19

Related Questions