#define MAXSIZE 256
fread(buff, sizeof(MAXSIZE), 1, infp);
Say at most we need to read 3 times, and after reading 2 times, the remaining stuff in infp is less than the size of MAXSIZE. How do we determine the size of information at the last read?
You can just check the return value of fread():
Return value
Number of objects read successfully, which may be less than count if an error or end-of-file condition occurs.
Like this:
size_t num = fread(...);
P.S.: as #chux commented, you are actually need to use fread(buff, MAXSIZE, 1, infp) instead.
From fread man page
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.
Man fread
Related
I'm trying to read data from a file into a buffer. The data in file is of 900K bytes. (seek to end of file and ftell()). Allocated the buffer in which the data is to be read of size 900K + 1 (to null terminate). My question is that fread() returns 900K but the I see the strlen(buffer) it shows lesser value and in the buffer at the last I can see something like ".....(truncated)". Why is this behavior? Is there a limit with fread() beyond which we cannot read into buffer and it will truncate it. Also why the return value of fread() says 900K even though actually it has read even less.?
strlen does something along these lines:
int strlen(char *str)
{
int len = 0;
while(*str++) len++;
return len;
}
If your file contains binary data (or if it's a text file with a UTF encoding and unused upper bytes) strlen is going to stop at the first 0x00 byte it encounters and return how many bytes into the file that was encountered. If you read a text file in a single-byte encoding like ANSI there won't be a null terminator and calling strlen will invoke undefined behavior.
If you want to determine how many bytes that fread successfully read out of the file, check its return value.1
If you want to determine the file size before reading a file, do this:
size_t len;
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
len will contain the file's size in bytes.
1: Assuming you called fread with parameter 2 set to 1 byte per element and didn't try to read more bytes than are actually in the file.
Your main question has already been answered, though it's worth notice that strlen is not designed to measure the size of an array but a NULL-terminated string. It probably prints a lower value because strlen returns the number of characters that appear before a null-char, so if you have nullchars ('\0') through your data, strlen will stop as soon as it finds one of them.
You should trust fread 's return value.
EDIT: as a note, fread MAY read less bytes than requested, and it can be caused by an error or an end of file. You can check it with ferror and feof, respectively.
I'm a beginner to C. I was wondering if it correct to check if the return value of fread(3) (which is the number of items read) is less than the number requested, rather than just 0, to detect EOF. For example, say you have
#include <stdio.h>
int main(void)
{
unsigned char buffer[1024];
while (fread(buffer, 1, sizeof(buffer), stdin) == sizeof(buffer))
{
printf("%s\n", "Not EOF yet");
}
printf("%s\n", "At EOF");
return 0;
}
Is this correct? Should the check for == sizeof(buffer) be != 0 instead? Is fread allowed to partially fill the buffer?
The reason I ask: It appears that read may return less than sizeof(buffer). Quoting the manpage:
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of
bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a ter-
minal), or because read() was interrupted by a signal.
However the same logic does not seem to apply to fread for some reason:
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).
So I would like confirmation that the check should indeed be == sizeof(buffer) and not != 0.
Thanks for helping!
The part of the manual you qouted says:
If an error occurs, or the end of the file is reached, the return
value is a short item count (or zero).
That means you can't use !=0 to check if no error has occurred as fread() could return a short item count.
The man page of fread() also states:
fread() does not distinguish between end-of-file and error, and
callers must use feof(3) and ferror(3) to determine which occurred.
So if the items count returned is less than requested, then you have to use feof() or ferror() to figure out which one occurred (If it's end-of-file then you can conclude that it's not an input error but the end of input on whatever stream you are reading from).
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?
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
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.
isn't it possible to read bytes left in a file that is smaller than buffer size?
char * buffer = (char *)malloc(size);
FILE * fp = fopen(filename, "rb");
while(fread(buffer, size, 1, fp)){
// do something
}
Let's assume size is 4 and file size is 17 bytes. I thought fread can handle last operation as well even if bytes left in file is smaller than buffer size, but apparently it just terminates while loop without reading one last byte.
I tried to use lower system call read() but I couldn't read any byte for some reason.
What should I do if fread cannot handle last part of bytes that is smaller than buffer size?
Yep, turn your parameters around.
Instead of requesting one block of size bytes, you should request size blocks of 1 bytes. Then the function will return how many blocks (bytes) it was able to read:
int nread;
while( 0 < (nread = fread(buffer, 1, size, fp)) ) ...
try using "man fread"
it clearly mention following things which itself answers your question:
SYNOPSIS
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
DESCRIPTION
fread() copies, into an array pointed to by ptr, up to nitems items of
data from the named input stream, where an item of data is a sequence
of bytes (not necessarily terminated by a null byte) of length size.
fread() stops appending bytes if an end-of-file or error condition is
encountered while reading stream, or if nitems items have been read.
fread() leaves the file pointer in stream, if defined, pointing to the
byte following the last byte read if there is one.
The argument size is typically sizeof(*ptr) where the pseudo-function
sizeof specifies the length of an item pointed to by ptr.
RETURN VALUE
fread(), return the number of items read.If size or nitems is 0, no
characters are read or written and 0 is returned.
The value returned will be less than nitems only if a read error or
end-of-file is encountered. The ferror() or feof() functions must be
used to distinguish between an error condition and an end-of-file
condition.
I have a question:
I am using fread to read a file.
typedef struct {
int ID1;
int ID2;
char string[256];
} Reg;
Reg *A = (Reg*) malloc(sizeof(Reg)*size);
size = FILESIZE/sizeof(Reg);
fread (A, sizeof(Reg), size, FILEREAD);
Using a loop, consecutively call this call, to make me read my entire file.
What will happen when I get near the end of the file, and I can not read "size" * sizeof (Reg), or if you are only available to read half this amount, what will happen with my array A. It will be completed? The function will return an error?
Knowing how the file was read by the fread through?
Edi1: Exactly, if the division is not exact, when I read the last bit smaller file size that I'll read things that are not on file, I'm wondering with my vector resize to the amount of bytes that I can read, or develop a dynamic better.
fread returns the number of records it read. Anything beyond that in your buffer may be mangled, do not rely on that data.
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.
The function will not read past the end of the file : the most likely occurrence is that you will get a bunch of full buffers and then a (final) partial buffer read, unless the file size is an exact multiple of your buffer length.
Your logic needs to accommodate this - the file size gives you the expected total number of records so it should not be hard to ignore trailing data in the buffer (after the final fread call) that corresponds to uninitialized records. A 'records remaining to read' counter would be one approach.
fread() returns the number of elements it could read. So you have to check the return value of fread() to find out how many elements in your array are valid.
It will return a short item count or zero if either an error occurred or EOF has is reached. You will have to use feof() ond ferror() in this case to check what condition is met.