Eric Sosman said:
As I understand it, fgets() is allowed to scribble on any or all
of the buffer's bytes, except that if there's an immediate end-of-file
it will touch none of them.
The wider question, I think, is "Why do you care?" Is this part
of a stratagem for dealing with lines that might contain '\0' or
some such?
I'm wondering what is the most efficient way to see if fgets() read an
entire line.
For example consider this:
char buf[16], *p;
FILE *fp;
/* initialise fp */
p = fgets(buf, sizeof(buf), fp);
from here you can do this:
/* check if the line is entirely read */
len = strlen(buf);
if (len == 15&& buf[14] != '\n') {
/* the line has not been read completely */
}
Possibly simpler, certainly briefer:
if (strchr(buf, '\n') == NULL) {
// incomplete line (or missing '\n' at EOF)
}
but you could also do:
buf[14] = '\n';
p = fgets(buf, sizeof(buf), fp);
if (buf[14] != '\n') {
/* the line has not been read completely */
... or consisted of thirteen characters plus '\n', and fgets()
dutifully set buf[14] = '\0'.
}
which seems more efficient.
Two thoughts: First, I/O is many orders of magnitude slower
than the CPU, so saving a few milliquavers probably just gets you
back to the idle loop sooner. Second, if it's really important to
get the answer ASAP you may be better off using getc() in a loop
and testing directly, rather than calling fgets() and then using
CSI forensics to post-analyze what it did.
It Would Be Nice If fgets() returned something more than a
single bit's worth of information, like the number of bytes read,
say, or a pointer to the '\0'. Unfortunately, the less-helpful
interface was already well-established before standardization got
underway, and (like some other features of the library) we're all
stuck with it.
Accept my best wishes for the holiday season, to you and yours
and all your vermiform appendices.