Bill Reid said:
Because sometimes I care...if only a little. And I've heard that
some systems don't "like" text files that aren't terminated by a
newline. So when I get a text file from an "unreliable" source,
I generally "fix" it, by appending the newline if needed...
Yeah, that's some good copy'n'pasting there...the documentation
for my "implementation" even reads pretty much the same...and yet,
confoundedly enough, the code works fine, and on other systems
too...
The quoted text is not in a constraint. In the C standard, the use of
the word "shall" outside a constraint means that, if the requirement
is violated, the behavior is undefined. "Works fine" is one possible
consequence of undefined behavior.
Hey, I'll go you one better, my "implementation" may "silently"
fail an fseek()...What WILL you do, WHAT WILL YOU DO?!??!!
If your implementation's fseek() function can fail without properly
reporting the error, then that's a bug; you should report it to the
vendor.
Suggestion "under advisement"...
Great, now I've two contrary opinions...
What two contrary opinions? I don't recall anyone saying that it's
guaranteed to work. If anyone did, they were mistaken.
ANOTHER problem!!! What WILL you do, WHAT WILL
YOU DO??!!?!!
I don't know. It's your program; what will you do? Error handling
isn't easy.
In any event, maybe I shouldn't have used the word "guarantee",
although I actually was looking for a little "spec lawyering" (and
came to the right place!). Maybe as an alternate question, just
how often WILL all these things fail?
Elsethread, Eric Sosman wrote:
| On some systems that mark line endings with something
| other than a one-byte sentinel, seeking to one byte before
| the end of the file and reading what you find there will be
| misleading at best.
For example, Windows uses a CR LF pair to mark end-of-line. If you
seek to one byte before the end of a properly terminated text file,
and then read a single character, you'll probably get a single LF
character, which will probably be translated to '\n'. Normally the CR
LF pair is what gets translated to '\n'. I'm actually not 100%
certain what will happen; it might depend on the C implementation.
Other systems use things other than character sequences to mark line
endings. VMS, for example, has a rather sophisticated
record-management system. Some mainframes use fixed-width lines
(inherited from punch card images), though I don't know whether this
is still in use. This kind of thing is exactly why the standard is so
vague about the behavior of fseek on text files.
If you don't mind the fact that your code is non-portable, that's
fine. The fseek trick is likely to be a whole heck of a lot faster
than the portable method of reading the entire file and seeing how it
ends.
For that matter, even that slow method isn't guaranteed to work. C99
7.19.2p2:
Whether the last line requires a terminating new-line character is
implementation-defined.
And the standard doesn't say what happens if the implementation
requires a terminating new-line and a particular file doesn't have
one. In my opinion, the behavior is undefined. It might report an
error, or it might quietly add a new-line on input.