wc double-counts lines due to using feof?
Closed
wc double-counts lines due to using feof?
It seems like the intended solution to wc is
while (!feof(f)) {
fread(result, 1, 1, f);
if (result[0] == '\n') {
num_lines++;
}
}
But I think in C it's more idiomatic to check the return value of file reading functions like fread than to use feof. The reason is feof returns true only if you read past end of file using another function. Thus the last fread will read nothing and not update result[0], so the last result[0] will be checked twice. This leads to a bug: if the last character in a file is \n
, the program will actually count 1 more than the number of newlines. (Thus it will count 2 lines for data/one
and 3 lines for data/two
.) Also see here: https://stackoverflow.com/a/12337620.
Here's a version which uses the return value of fread and doesn't double count.
while (fread(result, 1, 1, f) == 1) {
if (result[0] == '\n') {
num_lines++;
}
}
Could they just do this whole assignment with
getc()
instead? Then they can just compare its return value withEOF
.Although I guess that defeats the purpose of having to allocate a buffer to store the result.
Edited by Caleb C. SanderI think this is going to be quite confusing for them to debug. I would infer from "returns non-zero if we've run out of characters to read in the file and
0
otherwise" that it works likehasNext()
. If I noticed the line numbers were off, I would think it was a bug on my part, not a misunderstanding of how the functions work. I would do one of the following:- Remove the description of
feof()
and just say that the return value offread()
tells you how many characters were read (which may be less thannumber_to_read
if the end of the file is reached). - Change the description of
feof()
to say that it returns non-zero if the last call tofread()
tried to read past the end of the file.
- Remove the description of