I have a quick question regarding this line of code. Is this reading in the first record from a file? The == 1 bit is something I haven't come across before and it's thrown me off a bit, but I think it means to only read in the first record of the file into the struct variable.
The signature of fread() has an address of the destination variable place the data ("book" in this case), number of bytes to read in a block ("sizeof( book )" ), number of blocks to read (1), and the FILE stream ("library").
So what this line of code is doing is reading in one book-worth of data. This code will over-write the previous copy of course, so in your "while" loop you need to make a copy of it, or work with it how ever you need.
Thanks koothkeeper, but I already know how fread() works. What I was asking was if only the first record in the file is being read, because of the == 1 at the end.
No, you have this in a loop so it will continue reading records until fread() returns something other than 1. Since you said you already know how fread() works you should be able to figure out when the comparison will fail.
Edit: You should also know why it's == 1 and not some other number as well.
I understand how fread() works in the sense that I understand what the parameters mean. In the first post I said that I have never come across the == 1 bit before. I've only ever seen != NULL or != EOF at the end of the while condition.
koothkeeper explained how fread() works very well, but he/she didn't answer my question.
Are you telling me that the while loop will continue so long as there is one full record left to be read?
So then is the problem that you don't understand how to test a function's return value or you don't understand what this function returns? In that while loop you are checking the return value from the function.
If you don't really understand what this function is actually returning, I'm telling you to find and read the documentation for this function. The documentation will tell you exactly what this function returns, and when you actually read the documentation you should see that this function never returns NULL or EOF.
Return Value
The total number of elements successfully read is returned.
If this number differs from the count parameter, either a reading error occurred or the end-of-file was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror and feof, respectively.
If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged.
size_t is an unsigned integral type.
If you don't understand how to check the return value from functions then perhaps you need to review some basic function tutorials.
@Bogeyman: Sorry, I misunderstood your question. jlb is correct: That manual page for fread() discusses what is returned by that function.
Personally, I never write my "while" loops that way. I like to get the return code and handle each case in a switch statement. It's a little overkill, but it's easier to document when the code is split out IMHO. YMMV.
The documentation will tell you exactly what this function returns, and when you actually read the documentation you should see that this function never returns NULL or EOF.
My mistake, I was mixing up fread() with fscanf().
while(fread(&book, sizeof(book), 1, library) == 1)
So was I right in saying that this line will continue to read records from the file as long as there is at least one full record left to be read?
So was I right in saying that this line will continue to read records from the file as long as there is at least one full record left to be read?
Yes the loop will continue until fread() returns something other than the 1 in this case. But that doesn't necessarily mean it reads until EOF, there could also be some other type of read error.
And do you understand why you're comparing to == 1 and not some other number?
But that doesn't necessarily mean it reads until EOF, there could also be some other type of read error.
Might that be something like one of the fields in the records being missing, preventing the full block from being properly read?
And do you understand why you're comparing to == 1 and not some other number?
Well, possibly not. My understanding, which may well be wrong, is that == 1 signals that records will continue to be read as long as one full block is read, matching all the members of the struct variable.
If the line of code was while(fread(&book, sizeof(book), 2, library) == 1), nothing would be read in, as the specified number of blocks to be read, in the parameter, doesn't match the condition of the while loop.
That's what I think, but as I said I may well be wrong.
Might that be something like one of the fields in the records being missing, preventing the full block from being properly read?
It could be a disk failure, or some other issue you would need to query the operating system to find out what went wrong.. If you read the documentation you should see that there are at least two different failure modes and either ferror or feof will be set depending on what error caused the problem.
My understanding, which may well be wrong, is that == 1 signals that records will continue to be read as long as one full block is read, matching all the members of the struct variable.
Yes your understanding is probably wrong. You are checking for == 1 because you used 1 in the function call telling fread() to read 1 record.
In your last example: while(fread(&book, sizeof(book), 2, library) == 1)
You used 2 so you would need to check that 2 items were successfully read (== 2) not 1.
Remember fread() can read multiple records at one time, and if the return value doesn't equal the parameter there was a problem with the read.
I think I understand now. The parameter, which specifies how many blocks are to be read, must match the return value, in this case == 1, or nothing will be read from the file. Is that correct?
In this case yes. But if you are reading multiple items at a time then it is possible to read some but not all of the information requested. For example if you were trying to read 10 items and the function returned 5, it would mean that 5 items were properly read but the remaining 5 were not.
Yeah, so I could say while 10 items are properly read, write fwrite() those ten items to stdout or something, otherwise else print error message and end program.