Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #64802 > unrolled thread
| Started by | Paul N <gw7rib@aol.com> |
|---|---|
| First post | 2015-07-06 14:06 -0700 |
| Last post | 2015-07-30 15:42 -0700 |
| Articles | 19 — 6 participants |
Back to article view | Back to comp.lang.c
Fgets question Paul N <gw7rib@aol.com> - 2015-07-06 14:06 -0700
Re: Fgets question Barry Schwarz <schwarzb@dqel.com> - 2015-07-06 15:09 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-06 16:41 -0700
Re: Fgets question Paul N <gw7rib@aol.com> - 2015-07-07 15:16 -0700
Re: Fgets question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-06 23:13 +0100
Re: Fgets question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-07 00:57 +0100
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-06 16:29 -0700
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-11 05:16 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-11 14:04 -0700
Re: Fgets question Richard Damon <Richard@Damon-Family.org> - 2015-07-11 19:56 -0400
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-15 09:26 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-15 10:42 -0700
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-20 10:53 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-20 12:51 -0700
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-24 10:10 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-24 12:15 -0700
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-26 16:41 -0700
Re: Fgets question Keith Thompson <kst-u@mib.org> - 2015-07-27 11:42 -0700
Re: Fgets question Tim Rentsch <txr@alumni.caltech.edu> - 2015-07-30 15:42 -0700
| From | Paul N <gw7rib@aol.com> |
|---|---|
| Date | 2015-07-06 14:06 -0700 |
| Subject | Fgets question |
| Message-ID | <0b5d570e-eed5-4162-b5f9-44b2058639ee@googlegroups.com> |
I just had a moment of doubt about fgets, and rather to my surprise, neither MSDN or the C FAQ seemed to answer my question. If I read a file using fgets, which doesn't end with a newline, am I right in thinking that on attempting to read the last line, the function will read in the characters that are there, append a nul but no newline, and return a non-NULL value? And that next time I try fgets, it will return NULL? So in particular, if fgets(buff, len, fp) returns a non-NULL value, then buff[0] is not nul? Thanks. Paul.
[toc] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-07-06 15:09 -0700 |
| Message-ID | <qgulpapluk22fv9e33s05pr2gfojj44e96@4ax.com> |
| In reply to | #64802 |
On Mon, 6 Jul 2015 14:06:54 -0700 (PDT), Paul N <gw7rib@aol.com> wrote: >I just had a moment of doubt about fgets, and rather to my surprise, neither MSDN or the C FAQ seemed to answer my question. > >If I read a file using fgets, which doesn't end with a newline, am I right in thinking that on attempting to read the last line, >the function will read in the characters that are there, append a nul but no newline, and return a non-NULL value? And that next time I try fgets, it will return NULL? The answer to questions like this should come from the standard. n1570 says "The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array." followed by "The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned." So the answer to both questions is YES barring any I/O errors. >So in particular, if fgets(buff, len, fp) returns a non-NULL value, then buff[0] is not nul? That does not follow. What you can say is that the value stored in buff[0] has been replaced by the first character read from the file. Unfortunately, you cannot say what value that character has and it may indeed have the value '\0'. '\0' is significant in terminating strings. It has no special significance within a file or while performing file input. How a '\0' ended up in the file is a different question but neither fputc nor fwrite would have a problem doing so. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-06 16:41 -0700 |
| Message-ID | <lnlhesc0r4.fsf@kst-u.example.com> |
| In reply to | #64805 |
Barry Schwarz <schwarzb@dqel.com> writes:
> On Mon, 6 Jul 2015 14:06:54 -0700 (PDT), Paul N <gw7rib@aol.com>
> wrote:
[...]
>>So in particular, if fgets(buff, len, fp) returns a non-NULL value,
>>then buff[0] is not nul?
>
> That does not follow. What you can say is that the value stored in
> buff[0] has been replaced by the first character read from the file.
> Unfortunately, you cannot say what value that character has and it may
> indeed have the value '\0'.
>
> '\0' is significant in terminating strings. It has no special
> significance within a file or while performing file input. How a '\0'
> ended up in the file is a different question but neither fputc nor
> fwrite would have a problem doing so.
Good point, I didn't think about null characters in the file.
On the other hand, an implementation needn't permit null characters in
text files; only printable characters, horizontal tab, and new-line are
guaranteed.
On the other other hand, fgets() can be used on either text or binary
streams.
On the other**3 hand, if you're using fgets() on a binary stream, you're
likely doing something wrong.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Paul N <gw7rib@aol.com> |
|---|---|
| Date | 2015-07-07 15:16 -0700 |
| Message-ID | <8bd5abbf-e243-41cc-81bc-65416872d9f0@googlegroups.com> |
| In reply to | #64813 |
On Tuesday, 7 July 2015 00:41:45 UTC+1, Keith Thompson wrote: > Barry Schwarz <schwarzb@dqel.com> writes: > > On Mon, 6 Jul 2015 14:06:54 -0700 (PDT), Paul N <gw7rib@aol.com> > > wrote: > [...] > >>So in particular, if fgets(buff, len, fp) returns a non-NULL value, > >>then buff[0] is not nul? > > > > That does not follow. What you can say is that the value stored in > > buff[0] has been replaced by the first character read from the file. > > Unfortunately, you cannot say what value that character has and it may > > indeed have the value '\0'. > > > > '\0' is significant in terminating strings. It has no special > > significance within a file or while performing file input. How a '\0' > > ended up in the file is a different question but neither fputc nor > > fwrite would have a problem doing so. > > Good point, I didn't think about null characters in the file. > > On the other hand, an implementation needn't permit null characters in > text files; only printable characters, horizontal tab, and new-line are > guaranteed. > > On the other other hand, fgets() can be used on either text or binary > streams. > > On the other**3 hand, if you're using fgets() on a binary stream, you're > likely doing something wrong. Thanks to all - Barry, Keith and Ben - for your helpful replies! Paul.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-07-06 23:13 +0100 |
| Message-ID | <87si91szni.fsf@bsb.me.uk> |
| In reply to | #64802 |
Paul N <gw7rib@aol.com> writes:
> I just had a moment of doubt about fgets, and rather to my surprise,
> neither MSDN or the C FAQ seemed to answer my question.
>
> If I read a file using fgets, which doesn't end with a newline, am I
> right in thinking that on attempting to read the last line, the
> function will read in the characters that are there, append a nul but
> no newline, and return a non-NULL value?
This is what usually happens, though the standard says that, for a text
stream, the implementation may insist on a terminating new-line
character. ("Whether the last last line requires a terminating new-line
character is implementation-defined.")
> And that next time I try
> fgets, it will return NULL?
Yes.
> So in particular, if fgets(buff, len, fp) returns a non-NULL value,
> then buff[0] is not nul?
Yes.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-07-07 00:57 +0100 |
| Message-ID | <877fqcu9es.fsf@bsb.me.uk> |
| In reply to | #64806 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Paul N <gw7rib@aol.com> writes:
>
>> I just had a moment of doubt about fgets, and rather to my surprise,
>> neither MSDN or the C FAQ seemed to answer my question.
>>
>> If I read a file using fgets, which doesn't end with a newline, am I
>> right in thinking that on attempting to read the last line, the
>> function will read in the characters that are there, append a nul but
>> no newline, and return a non-NULL value?
>
> This is what usually happens, though the standard says that, for a text
> stream, the implementation may insist on a terminating new-line
> character. ("Whether the last last line requires a terminating new-line
> character is implementation-defined.")
>
>> And that next time I try
>> fgets, it will return NULL?
>
> Yes.
>
>> So in particular, if fgets(buff, len, fp) returns a non-NULL value,
>> then buff[0] is not nul?
>
> Yes.
This needs to be corrected in the light of Barry Schwarz's better reply:
yes only provided the stream does not have nulls in it. But if you have
nulls in the stream (specifically at the end) you will have trouble
knowing what stream really contains -- you pretty much have to assume
there are none at the end. Nulls not at the end of the stream are not a
problem, though it's fiddly to deal with them correctly.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-06 16:29 -0700 |
| Message-ID | <lnpp44c1bq.fsf@kst-u.example.com> |
| In reply to | #64802 |
Paul N <gw7rib@aol.com> writes:
> I just had a moment of doubt about fgets, and rather to my surprise,
> neither MSDN or the C FAQ seemed to answer my question.
>
> If I read a file using fgets, which doesn't end with a newline, am I
> right in thinking that on attempting to read the last line, the
> function will read in the characters that are there, append a nul but
> no newline, and return a non-NULL value? And that next time I try
> fgets, it will return NULL?
Yes, generally. I believe the description of the fgets() function in
the standard makes this reasonably clear (N1570 7.21.7.2p2):
The fgets function reads at most one less than the number of
characters specified by n from the stream pointed to by stream
into the array pointed to by s. No additional characters are
read after a new-line character (which is retained) or after
end-of-file. A null character is written immediately after the
last character read into the array.
p3:
The fgets function returns s if successful. If end-of-file is
encountered and no characters have been read into the array,
the contents of the array remain unchanged and a null pointer
is returned. If a read error occurs during the operation, the
array contents are indeterminate and a null pointer is returned.
> So in particular, if fgets(buff, len, fp) returns a non-NULL value,
> then buff[0] is not nul?
Yes, I believe that's correct.
*However* the description of text streams in 7.21.2 says that a trailing
new-line may be required. (By implication, if there is no new-line at
the very end of the file, the behavior is undefined.)
Data read in from a text stream will necessarily compare equal
to the data that were earlier written out to that stream only
if: the data consist only of printing characters and the control
characters horizontal tab and new-line; no new-line character is
immediately preceded by space characters; and the last character
is a new-line character.
On Unix-like systems, and *I think* on Windows systems, omitting the
newline at the end of the last line is acceptable.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-11 05:16 -0700 |
| Message-ID | <kfnfv4u28k0.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #64812 |
Keith Thompson <kst-u@mib.org> writes:
> Paul N <gw7rib@aol.com> writes:
>> I just had a moment of doubt about fgets, and rather to my surprise,
>> neither MSDN or the C FAQ seemed to answer my question.
>>
>> If I read a file using fgets, which doesn't end with a newline, am I
>> right in thinking that on attempting to read the last line, the
>> function will read in the characters that are there, append a nul but
>> no newline, and return a non-NULL value? And that next time I try
>> fgets, it will return NULL?
>
> Yes, generally. I believe the description of the fgets() function in
> the standard makes this reasonably clear (N1570 7.21.7.2p2):
>
> The fgets function reads at most one less than the number of
> characters specified by n from the stream pointed to by stream
> into the array pointed to by s. No additional characters are
> read after a new-line character (which is retained) or after
> end-of-file. A null character is written immediately after the
> last character read into the array.
>
> p3:
>
> The fgets function returns s if successful. If end-of-file is
> encountered and no characters have been read into the array,
> the contents of the array remain unchanged and a null pointer
> is returned. If a read error occurs during the operation, the
> array contents are indeterminate and a null pointer is returned.
>
>> So in particular, if fgets(buff, len, fp) returns a non-NULL value,
>> then buff[0] is not nul?
>
> Yes, I believe that's correct.
>
> *However* the description of text streams in 7.21.2 says that a trailing
> new-line may be required. (By implication, if there is no new-line at
> the very end of the file, the behavior is undefined.) [snip]
FWIW I think you may be reading that wrongly. The requirement is not
on the program but on the line. ("Whether the last line requires a
terminating new-line character is implementation-defined.") It's
not obvious that leaving off a final new-line was meant to be (or
was meant not to be) undefined behavior.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-11 14:04 -0700 |
| Message-ID | <lnr3oepfri.fsf@kst-u.example.com> |
| In reply to | #65254 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> *However* the description of text streams in 7.21.2 says that a trailing
>> new-line may be required. (By implication, if there is no new-line at
>> the very end of the file, the behavior is undefined.) [snip]
>
> FWIW I think you may be reading that wrongly. The requirement is not
> on the program but on the line. ("Whether the last line requires a
> terminating new-line character is implementation-defined.") It's
> not obvious that leaving off a final new-line was meant to be (or
> was meant not to be) undefined behavior.
Can you clarify what a requirement *on the line* means?
Implementations have behavior; lines don't. I think it's just
slightly odd wording. In any case, it's the implementation that
has to specify whether it's required or not.
If, for a given implementation, the last line doesn't require a
terminating new-line, writing a text file with no newline and then
reading it has well defined behavior. If the last line *does*
require it, then the standard doesn't say what the behavior of a
program that omits it is -- thus, undefined behavior.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-07-11 19:56 -0400 |
| Message-ID | <93iox.79302$kh3.70861@fx08.iad> |
| In reply to | #65342 |
On 7/11/15 5:04 PM, Keith Thompson wrote:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
> [...]
>>> *However* the description of text streams in 7.21.2 says that a trailing
>>> new-line may be required. (By implication, if there is no new-line at
>>> the very end of the file, the behavior is undefined.) [snip]
>>
>> FWIW I think you may be reading that wrongly. The requirement is not
>> on the program but on the line. ("Whether the last line requires a
>> terminating new-line character is implementation-defined.") It's
>> not obvious that leaving off a final new-line was meant to be (or
>> was meant not to be) undefined behavior.
>
> Can you clarify what a requirement *on the line* means?
> Implementations have behavior; lines don't. I think it's just
> slightly odd wording. In any case, it's the implementation that
> has to specify whether it's required or not.
>
> If, for a given implementation, the last line doesn't require a
> terminating new-line, writing a text file with no newline and then
> reading it has well defined behavior. If the last line *does*
> require it, then the standard doesn't say what the behavior of a
> program that omits it is -- thus, undefined behavior.
>
My impression is that these are the requirements to get the promise that
the input data matches the output data.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-15 09:26 -0700 |
| Message-ID | <kfnr3o9qtds.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #65342 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>
> [...]
>
>>> *However* the description of text streams in 7.21.2 says that a trailing
>>> new-line may be required. (By implication, if there is no new-line at
>>> the very end of the file, the behavior is undefined.) [snip]
>>
>> FWIW I think you may be reading that wrongly. The requirement is not
>> on the program but on the line. ("Whether the last line requires a
>> terminating new-line character is implementation-defined.") It's
>> not obvious that leaving off a final new-line was meant to be (or
>> was meant not to be) undefined behavior.
>
> Can you clarify what a requirement *on the line* means?
> Implementations have behavior; lines don't. I think it's just
> slightly odd wording. In any case, it's the implementation that
> has to specify whether it's required or not.
I agree the wording is odd. At some level that's the point I'm
making, that the odd wording may portend an unexpected meaning or
interpretation. For example, the sentence quoted above might
mean "Whether the last line requires a terminating new-line
character _to be considered part of the text stream_ is
implementation-defined." Thus any characters sent after the last
newline transmitted simply are not part of the text stream.
> If, for a given implementation, the last line doesn't require a
> terminating new-line, writing a text file with no newline and then
> reading it has well defined behavior. If the last line *does*
> require it, then the standard doesn't say what the behavior of a
> program that omits it is -- thus, undefined behavior.
If the last line requires a newline to be considered part of a
text stream, then not sending a final newline simply means the
last line isn't included in the output. That is a definition of
behavior, even if it is not stated as explicitly as we would
like. Note that I am not saying that the Standard _must_ mean
this, only that it _might_ mean this. At this point I haven't
seen any compelling evidence to decide the matter either way.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-15 10:42 -0700 |
| Message-ID | <lnpp3tjp0u.fsf@kst-u.example.com> |
| In reply to | #65633 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>>
>> [...]
>>
>>>> *However* the description of text streams in 7.21.2 says that a trailing
>>>> new-line may be required. (By implication, if there is no new-line at
>>>> the very end of the file, the behavior is undefined.) [snip]
>>>
>>> FWIW I think you may be reading that wrongly. The requirement is not
>>> on the program but on the line. ("Whether the last line requires a
>>> terminating new-line character is implementation-defined.") It's
>>> not obvious that leaving off a final new-line was meant to be (or
>>> was meant not to be) undefined behavior.
>>
>> Can you clarify what a requirement *on the line* means?
>> Implementations have behavior; lines don't. I think it's just
>> slightly odd wording. In any case, it's the implementation that
>> has to specify whether it's required or not.
>
> I agree the wording is odd. At some level that's the point I'm
> making, that the odd wording may portend an unexpected meaning or
> interpretation. For example, the sentence quoted above might
> mean "Whether the last line requires a terminating new-line
> character _to be considered part of the text stream_ is
> implementation-defined." Thus any characters sent after the last
> newline transmitted simply are not part of the text stream.
That's certainly one possible behavior. But the standard doesn't
say that that's how it behaves, and I don't think it's reasonable
to assume that that one specific behavior is what was intended.
For an implementation where the last line "requires" a terminating
new-line, it would be equally reasonable for an fgets() call on the last
line to behave as if the new-line character were there. Or, on a system
where text files are not represented as simple byte streams as they are
on Unix, a text file without a terminating new-line on the last line
might be ill-formed, and an fgets() call might return an error
indication -- perhaps even before attempting to read the last line.
(I probably should have written that in terms of fgetc(), since the
behavior of fgets() is defined in terms of readin characters, but I'm
too lazy to go back and change it.)
In fact, the standard doesn't say what the behavior is at all --
which is, by definition, undefined behavior.
>> If, for a given implementation, the last line doesn't require a
>> terminating new-line, writing a text file with no newline and then
>> reading it has well defined behavior. If the last line *does*
>> require it, then the standard doesn't say what the behavior of a
>> program that omits it is -- thus, undefined behavior.
>
> If the last line requires a newline to be considered part of a
> text stream, then not sending a final newline simply means the
> last line isn't included in the output. That is a definition of
> behavior, even if it is not stated as explicitly as we would
> like. Note that I am not saying that the Standard _must_ mean
> this, only that it _might_ mean this. At this point I haven't
> seen any compelling evidence to decide the matter either way.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-20 10:53 -0700 |
| Message-ID | <kfntwsylnr6.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #65638 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>> Keith Thompson <kst-u@mib.org> writes:
>>>
>>> [...]
>>>
>>>>> *However* the description of text streams in 7.21.2 says that a trailing
>>>>> new-line may be required. (By implication, if there is no new-line at
>>>>> the very end of the file, the behavior is undefined.) [snip]
>>>>
>>>> FWIW I think you may be reading that wrongly. The requirement is not
>>>> on the program but on the line. ("Whether the last line requires a
>>>> terminating new-line character is implementation-defined.") It's
>>>> not obvious that leaving off a final new-line was meant to be (or
>>>> was meant not to be) undefined behavior.
>>>
>>> Can you clarify what a requirement *on the line* means?
>>> Implementations have behavior; lines don't. I think it's just
>>> slightly odd wording. In any case, it's the implementation that
>>> has to specify whether it's required or not.
>>
>> I agree the wording is odd. At some level that's the point I'm
>> making, that the odd wording may portend an unexpected meaning or
>> interpretation. For example, the sentence quoted above might
>> mean "Whether the last line requires a terminating new-line
>> character _to be considered part of the text stream_ is
>> implementation-defined." Thus any characters sent after the last
>> newline transmitted simply are not part of the text stream.
>
> That's certainly one possible behavior. But the standard doesn't
> say that that's how it behaves, and I don't think it's reasonable
> to assume that that one specific behavior is what was intended.
>
> For an implementation where the last line "requires" a terminating
> new-line, it would be equally reasonable for an fgets() call on
> the last line to behave as if the new-line character were there.
> Or, on a system where text files are not represented as simple
> byte streams as they are on Unix, a text file without a
> terminating new-line on the last line might be ill-formed, and an
> fgets() call might return an error indication -- perhaps even
> before attempting to read the last line.
>
> (I probably should have written that in terms of fgetc(), since
> the behavior of fgets() is defined in terms of readin characters,
> but I'm too lazy to go back and change it.)
>
> In fact, the standard doesn't say what the behavior is at all --
> which is, by definition, undefined behavior.
You keep saying that the Standard doesn't say what the behavior
is and therefore that the result is undefined behavior.
My position is that the Standard /may/ say what the behavior is,
depending on how one interprets the key sentence in question.
Certainly if the Standard does say what the behavior is then
the behavior is not undefined.
I agree that there are different ways of interpreting the key
sentence mentioned, and I agree that different people might
reach different conclusions about whether what the Standard
says should be construed to ascribe some particular behavior
in such cases. I think we both agree that the existing wording
is somewhat murky and merits clarification. Having said all
that, I think it's wrong to say categorically the such cases
must be undefined behavior, because what the Standard has to say
on that question may depend on how one interprets all the
relevant passages.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-20 12:51 -0700 |
| Message-ID | <lnfv4ifvzj.fsf@kst-u.example.com> |
| In reply to | #66032 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>
>>>> [...]
>>>>
>>>>>> *However* the description of text streams in 7.21.2 says that a trailing
>>>>>> new-line may be required. (By implication, if there is no new-line at
>>>>>> the very end of the file, the behavior is undefined.) [snip]
>>>>>
>>>>> FWIW I think you may be reading that wrongly. The requirement is not
>>>>> on the program but on the line. ("Whether the last line requires a
>>>>> terminating new-line character is implementation-defined.") It's
>>>>> not obvious that leaving off a final new-line was meant to be (or
>>>>> was meant not to be) undefined behavior.
>>>>
>>>> Can you clarify what a requirement *on the line* means?
>>>> Implementations have behavior; lines don't. I think it's just
>>>> slightly odd wording. In any case, it's the implementation that
>>>> has to specify whether it's required or not.
>>>
>>> I agree the wording is odd. At some level that's the point I'm
>>> making, that the odd wording may portend an unexpected meaning or
>>> interpretation. For example, the sentence quoted above might
>>> mean "Whether the last line requires a terminating new-line
>>> character _to be considered part of the text stream_ is
>>> implementation-defined." Thus any characters sent after the last
>>> newline transmitted simply are not part of the text stream.
>>
>> That's certainly one possible behavior. But the standard doesn't
>> say that that's how it behaves, and I don't think it's reasonable
>> to assume that that one specific behavior is what was intended.
>>
>> For an implementation where the last line "requires" a terminating
>> new-line, it would be equally reasonable for an fgets() call on
>> the last line to behave as if the new-line character were there.
>> Or, on a system where text files are not represented as simple
>> byte streams as they are on Unix, a text file without a
>> terminating new-line on the last line might be ill-formed, and an
>> fgets() call might return an error indication -- perhaps even
>> before attempting to read the last line.
>>
>> (I probably should have written that in terms of fgetc(), since
>> the behavior of fgets() is defined in terms of readin characters,
>> but I'm too lazy to go back and change it.)
>>
>> In fact, the standard doesn't say what the behavior is at all --
>> which is, by definition, undefined behavior.
>
> You keep saying that the Standard doesn't say what the behavior
> is and therefore that the result is undefined behavior.
Yes.
> My position is that the Standard /may/ say what the behavior is,
> depending on how one interprets the key sentence in question.
> Certainly if the Standard does say what the behavior is then
> the behavior is not undefined.
>
> I agree that there are different ways of interpreting the key
> sentence mentioned, and I agree that different people might
> reach different conclusions about whether what the Standard
> says should be construed to ascribe some particular behavior
> in such cases. I think we both agree that the existing wording
> is somewhat murky and merits clarification. Having said all
> that, I think it's wrong to say categorically the such cases
> must be undefined behavior, because what the Standard has to say
> on that question may depend on how one interprets all the
> relevant passages.
To repeat the relevant passage (N1570 7.21.2p2):
A text stream is an ordered sequence of characters composed into
lines, each line consisting of zero or more characters plus a
terminating new-line character. Whether the last line requires
a terminating new-line character is implementation-defined.
For an implementation where the last line "requires" a terminating
new-line character, you suggest that the implementation could ignore any
characters following the last new-line. It's equally possible that an
implementation could behave as if the terminating new-line were there,
so you could write "hello" to a text stream and then read "hello\n" from
the same text stream. I see no clue in the standard that either
behavior is preferred over the other -- or over any of a number of other
plausible behaviors.
There may have been some *intent* to define the behavior, but the
standard just doesn't do so.
I agree that that passage is badly worded, even if the intent is for the
behavior to be undefined.
Incidentally, I find it plausible that the behavior is intended to be
undefined. I can imagine an system where a text file *must*
have a new-line on the last line, and reading a file that violates that
could have bad consequences. I think the committee intended to allow
conforming implementations for such systems.
The following paragraph discusses binary streams, and a similar
consideration for what the end of such a stream looks like. For binary
streams, the standard explicitly makes the behavior
implementation-defined:
Such a stream may, however, have an implementation-deļ¬ned
number of null characters appended to the end of the stream."
The failure to do so for text streams might have been an unintentional
oversight, but it's plausible that it was deliberate.
The bottom line is that I disagree with your assertion that the standard
might define the behavior for text streams. By my reading, it simply
doesn't.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-24 10:10 -0700 |
| Message-ID | <kfnio99h465.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #66050 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>>
>>>>> [...]
>>>>>
>>>>>>> *However* the description of text streams in 7.21.2 says that a
>>>>>>> trailing new-line may be required. (By implication, if there is
>>>>>>> no new-line at the very end of the file, the behavior is
>>>>>>> undefined.) [snip]
>>>>>>
>>>>>> FWIW I think you may be reading that wrongly. The requirement is not
>>>>>> on the program but on the line. ("Whether the last line requires a
>>>>>> terminating new-line character is implementation-defined.") It's not
>>>>>> obvious that leaving off a final new-line was meant to be (or was
>>>>>> meant not to be) undefined behavior.
>>>>>
>>>>> Can you clarify what a requirement *on the line* means?
>>>>> Implementations have behavior; lines don't. I think it's just
>>>>> slightly odd wording. In any case, it's the implementation that
>>>>> has to specify whether it's required or not.
>>>>
>>>> I agree the wording is odd. At some level that's the point I'm
>>>> making, that the odd wording may portend an unexpected meaning or
>>>> interpretation. For example, the sentence quoted above might
>>>> mean "Whether the last line requires a terminating new-line
>>>> character _to be considered part of the text stream_ is
>>>> implementation-defined." Thus any characters sent after the last
>>>> newline transmitted simply are not part of the text stream.
>>>
>>> That's certainly one possible behavior. But the standard doesn't
>>> say that that's how it behaves, and I don't think it's reasonable
>>> to assume that that one specific behavior is what was intended.
>>>
>>> For an implementation where the last line "requires" a terminating
>>> new-line, it would be equally reasonable for an fgets() call on
>>> the last line to behave as if the new-line character were there.
>>> Or, on a system where text files are not represented as simple
>>> byte streams as they are on Unix, a text file without a
>>> terminating new-line on the last line might be ill-formed, and an
>>> fgets() call might return an error indication -- perhaps even
>>> before attempting to read the last line.
>>>
>>> (I probably should have written that in terms of fgetc(), since
>>> the behavior of fgets() is defined in terms of readin characters,
>>> but I'm too lazy to go back and change it.)
>>>
>>> In fact, the standard doesn't say what the behavior is at all --
>>> which is, by definition, undefined behavior.
>>
>> You keep saying that the Standard doesn't say what the behavior
>> is and therefore that the result is undefined behavior.
>
> Yes.
>
>> My position is that the Standard /may/ say what the behavior is,
>> depending on how one interprets the key sentence in question.
>> Certainly if the Standard does say what the behavior is then
>> the behavior is not undefined.
>>
>> I agree that there are different ways of interpreting the key
>> sentence mentioned, and I agree that different people might
>> reach different conclusions about whether what the Standard
>> says should be construed to ascribe some particular behavior
>> in such cases. I think we both agree that the existing wording
>> is somewhat murky and merits clarification. Having said all
>> that, I think it's wrong to say categorically the such cases
>> must be undefined behavior, because what the Standard has to say
>> on that question may depend on how one interprets all the
>> relevant passages.
>
> To repeat the relevant passage (N1570 7.21.2p2):
>
> A text stream is an ordered sequence of characters composed into
> lines, each line consisting of zero or more characters plus a
> terminating new-line character. Whether the last line requires
> a terminating new-line character is implementation-defined.
>
> For an implementation where the last line "requires" a terminating
> new-line character, you suggest that the implementation could
> ignore any characters following the last new-line. It's equally
> possible that an implementation could behave as if the terminating
> new-line were there, so you could write "hello" to a text stream
> and then read "hello\n" from the same text stream. I see no clue
> in the standard that either behavior is preferred over the other
> -- or over any of a number of other plausible behaviors.
>
> There may have been some *intent* to define the behavior, but the
> standard just doesn't do so.
I believe whether that is so depends on how one interprets
the text - for some interpretations it does, for other it does
not. Do you agree with that, or do you disagree?
> I agree that that passage is badly worded, even if the intent is for the
> behavior to be undefined.
Okay, glad we agree on that.
> Incidentally, I find it plausible that the behavior is intended to be
> undefined. I can imagine an system where a text file *must*
> have a new-line on the last line, and reading a file that violates that
> could have bad consequences. I think the committee intended to allow
> conforming implementations for such systems.
I believe it is possible, and perhaps even likely, that the
intention was for the behavior to be undefined. My point is
that what is intended is not completely clear, and the text
could be read in several different ways, some of which do
not define the behavior, and some of which do define (at
least partially) the behavior.
> The following paragraph discusses binary streams, and a similar
> consideration for what the end of such a stream looks like. For
> binary streams, the standard explicitly makes the behavior
> implementation-defined:
>
> Such a stream may, however, have an implementation-defined
> number of null characters appended to the end of the stream."
>
> The failure to do so for text streams might have been an unintentional
> oversight, but it's plausible that it was deliberate.
To my way of thinking the two situations are not necessarily
analogous. They /may/ be analogous, but I am not aware of
anything in the Standard to conclude they /must/ be analogous.
> The bottom line is that I disagree with your assertion that the
> standard might define the behavior for text streams. By my
> reading, it simply doesn't.
Yes, by your reading. Isn't it possible that other readings
might define it?
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-24 12:15 -0700 |
| Message-ID | <ln6159z7s2.fsf@kst-u.example.com> |
| In reply to | #66289 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> To repeat the relevant passage (N1570 7.21.2p2):
>>
>> A text stream is an ordered sequence of characters composed into
>> lines, each line consisting of zero or more characters plus a
>> terminating new-line character. Whether the last line requires
>> a terminating new-line character is implementation-defined.
>>
>> For an implementation where the last line "requires" a terminating
>> new-line character, you suggest that the implementation could
>> ignore any characters following the last new-line. It's equally
>> possible that an implementation could behave as if the terminating
>> new-line were there, so you could write "hello" to a text stream
>> and then read "hello\n" from the same text stream. I see no clue
>> in the standard that either behavior is preferred over the other
>> -- or over any of a number of other plausible behaviors.
>>
>> There may have been some *intent* to define the behavior, but the
>> standard just doesn't do so.
>
> I believe whether that is so depends on how one interprets
> the text - for some interpretations it does, for other it does
> not. Do you agree with that, or do you disagree?
Not in this case, no. I see no hint of any definition of what
the behavior should be if a new-line character is required and is
not present.
It's badly worded because it's the standard's job to impose
requirements on implementations and on programmers; here it's trying
to impose a requirement on a line in a text stream. The bad wording
makes it difficult to infer the intent.
You suggest an interpretation whereby any characters after the
last new-line are not part of the stream. I see no possible way
to infer that meaning from the text. It's certainly one possible
reasonable behavior -- but adding an implicit new-line is equally
reasonable given the way it's worded.
>> I agree that that passage is badly worded, even if the intent is for the
>> behavior to be undefined.
>
> Okay, glad we agree on that.
>
>> Incidentally, I find it plausible that the behavior is intended to be
>> undefined. I can imagine an system where a text file *must*
>> have a new-line on the last line, and reading a file that violates that
>> could have bad consequences. I think the committee intended to allow
>> conforming implementations for such systems.
>
> I believe it is possible, and perhaps even likely, that the
> intention was for the behavior to be undefined. My point is
> that what is intended is not completely clear, and the text
> could be read in several different ways, some of which do
> not define the behavior,
Agreed.
> and some of which do define (at
> least partially) the behavior.
Since I see no definition of the behavior, I can't agree with that.
I can accept that the committee might have intended to define the
behavior, but they failed to do so.
[...]
>> The bottom line is that I disagree with your assertion that the
>> standard might define the behavior for text streams. By my
>> reading, it simply doesn't.
>
> Yes, by your reading. Isn't it possible that other readings
> might define it?
Not as far as I can see.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-26 16:41 -0700 |
| Message-ID | <kfnpp3eebbi.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #66303 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: >> Keith Thompson <kst-u@mib.org> writes: > > [snipping most as being mostly a repeat] > >>> The bottom line is that I disagree with your assertion that the >>> standard might define the behavior for text streams. By my >>> reading, it simply doesn't. >> >> Yes, by your reading. Isn't it possible that other readings >> might define it? > > Not as far as I can see. It surprises me that you think something definitive can be said about all possible readings, especially since you agree that some of the pertinent language is rather oddly worded (my paraphrase, I don't mean to put words in your mouth). However at this point I don't think there is any more to say except that we have different opinions on the question of whether some ways of reading the Standard may define or partially define the semantics in such cases.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-07-27 11:42 -0700 |
| Message-ID | <lnzj2ho31i.fsf@kst-u.example.com> |
| In reply to | #66430 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>> [snipping most as being mostly a repeat]
>>
>>>> The bottom line is that I disagree with your assertion that the
>>>> standard might define the behavior for text streams. By my
>>>> reading, it simply doesn't.
>>>
>>> Yes, by your reading. Isn't it possible that other readings
>>> might define it?
>>
>> Not as far as I can see.
>
> It surprises me that you think something definitive can be
> said about all possible readings, especially since you
> agree that some of the pertinent language is rather oddly
> worded (my paraphrase, I don't mean to put words in your
> mouth). However at this point I don't think there is any
> more to say except that we have different opinions on the
> question of whether some ways of reading the Standard may
> define or partially define the semantics in such cases.
I wrote "Not as far as I can see." That's a definitive statement about
what I'm able to see in the standard, not about the standard itself.
My statement about the standard itself, that it doesn't define the
behavior in the absence of a terminating new-line, is not quite as
definitive.
A text stream is an ordered sequence of characters composed into
lines, each line consisting of zero or more characters plus a
terminating new-line character. Whether the last line requires
a terminating new-line character is implementation-defined.
One possible interpretation is, as you suggest, that any characters
following the last new-line in a text stream are ignored. Another is
that an implicit new-line is added to the end of the stream (the
stream "requires" a terminating new-line, so the implementation
gives it one). Yet another is that the stream is ill-formed,
and any attempt to read it, or to read to the end of it, can fail
with an I/O error.
I see nothing in the standard that suggests any of those alternatives
over the others. I therefore conclude (tentatively) that the standard
does not define the behavior, which is precisely equivalent to saying
that the behavior is undefined.
If the committee published a response to a defect report specifying some
particular behavior, I would accept it. In the absence of any such
statement, I can only go by the wording in the standard itself.
Do you see something that I'm missing?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-07-30 15:42 -0700 |
| Message-ID | <kfn1tfpclo5.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #66454 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: >> Keith Thompson <kst-u@mib.org> writes: >>> Tim Rentsch <txr@alumni.caltech.edu> writes: >>>> Keith Thompson <kst-u@mib.org> writes: >>> >>> [snipping most as being mostly a repeat] >>> >>>>> The bottom line is that I disagree with your assertion that the >>>>> standard might define the behavior for text streams. By my >>>>> reading, it simply doesn't. >>>> >>>> Yes, by your reading. Isn't it possible that other readings >>>> might define it? >>> >>> Not as far as I can see. >> >> It surprises me that you think something definitive can be >> said about all possible readings, especially since you >> agree that some of the pertinent language is rather oddly >> worded (my paraphrase, I don't mean to put words in your >> mouth). However at this point I don't think there is any >> more to say except that we have different opinions on the >> question of whether some ways of reading the Standard may >> define or partially define the semantics in such cases. > > I wrote "Not as far as I can see." That's a definitive statement > about what I'm able to see in the standard, not about the standard > itself. My statement about the standard itself, that it doesn't > define the behavior in the absence of a terminating new-line, is > not quite as definitive. > > A text stream is an ordered sequence of characters composed into > lines, each line consisting of zero or more characters plus a > terminating new-line character. Whether the last line requires > a terminating new-line character is implementation-defined. > > One possible interpretation is, as you suggest, that any > characters following the last new-line in a text stream are > ignored. Another is that an implicit new-line is added to the end > of the stream (the stream "requires" a terminating new-line, so > the implementation gives it one). Yet another is that the stream > is ill-formed, and any attempt to read it, or to read to the end > of it, can fail with an I/O error. > > I see nothing in the standard that suggests any of those > alternatives over the others. I therefore conclude (tentatively) > that the standard does not define the behavior, which is precisely > equivalent to saying that the behavior is undefined. > > If the committee published a response to a defect report > specifying some particular behavior, I would accept it. In the > absence of any such statement, I can only go by the wording in the > standard itself. > > Do you see something that I'm missing? I'll tell you how I look at it. First, I think the text is murky enough so it can't be said absolutely either that the behavior is defined or that the behavior is undefined. If forced to pick a side I would argue that the behavior is at least partially defined, but that's only if I had to pick one side or the other. I believe the intention was for there _not_ to be undefined behavior in this case. It isn't obvious to me what the limits are in terms of what an implementation could do if text-streams required a newline on the last line and didn't get one, but I don't think it was meant to be as unconstrained as undefined behavior. This case doesn't seem to rise to the same level as other cases of undefined behavior. Now consider the odd line in question - "Whether the last line requires a terminating new-line character" etc. By itself this line neither adds nor takes away behavior; it simply is part of the definition of a text stream. If no behavior is taken away then the behavior cannot be undefined, since it is defined otherwise. Also, note the second-to-last line in that same paragraph, which says "Data read in from a text stream will necessarily compare equal to the data that were earlier written out to that stream only if: [...] and the last character is a new-line character." The last part holds even for implementations that do not require a final newline. Why is that? What then is the point of not requiring a final newline, if you can't count on the behavior? Also note that the last part there would not be necessary if failing to output a final newline were undefined behavior. Another consideration is what happens on input. Suppose we are reading a file under an implementation whose text streams require a newline on the final line, and the file in question doesn't have one. Is that undefined behavior? That's pretty awful - through no fault of the program it can misbehave arbitrarily. That result seems wrong enough so that I'm inclined to believe it is not what was intended. My guess at this point is that the final-newline-requirement relates to the question of whether output without a final terminating newline can be relied on during subsequent input. That is, the second line of that paragraph and the penultimate line of that paragraph are tried together in some way. Whether that is true or not, I don't see a convincing argument one way or the other that the behavior in such cases is (un)defined.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web