Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fread() return value in C

Tags:

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?

like image 281
Jordan Camp Avatar asked Feb 08 '15 19:02

Jordan Camp


People also ask

What does fread () return in C?

fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count . Use the feof or ferror function to distinguish a read error from an end-of-file condition.

What does fwrite return in C?

The fwrite() function returns the number of members successfully written, which may be less than nitems if a write error is encountered. If size or nitems is 0, fwrite() returns 0 and the state of the stream remains unchanged.

How does C fread work?

In the C Programming Language, the fread function reads nmemb elements (each element is the number of bytes indicated by size) from the stream pointed to by stream and stores them in ptr.

What is the difference between read () and fread ()?

read() is a low level, unbuffered read. It makes a direct system call on UNIX. fread() is part of the C library, and provides buffered reads. It is usually implemented by calling read() in order to fill its buffer.


2 Answers

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:

  • What is the rationale for fread/fwrite taking size and count as arguments?

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:

  • https://stackoverflow.com/a/296305/1025391
like image 92
moooeeeep Avatar answered Oct 08 '22 21:10

moooeeeep


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.

like image 20
Sourav Ghosh Avatar answered Oct 08 '22 23:10

Sourav Ghosh