Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #95489 > unrolled thread
| Started by | asetofsymbols@gmail.com |
|---|---|
| First post | 2016-11-01 01:50 -0700 |
| Last post | 2016-11-02 01:42 -0700 |
| Articles | 20 on this page of 30 — 10 participants |
Back to article view | Back to comp.lang.c
scanf used for to get a line asetofsymbols@gmail.com - 2016-11-01 01:50 -0700
scanf used for to get a line asetofsymbols@gmail.com - 2016-11-01 01:55 -0700
Re: scanf used for to get a line mark.bluemel@gmail.com - 2016-11-01 03:55 -0700
Re: scanf used for to get a line "Charles Richmond" <numerist@aquaporin4.com> - 2016-11-03 11:23 -0500
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-03 09:38 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-03 10:08 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-03 11:29 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-03 14:37 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-03 16:34 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-04 10:21 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-04 11:46 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-04 15:04 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-04 16:44 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-04 17:13 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-04 19:12 -0700
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-05 14:10 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-05 14:22 -0700
Re: scanf used for to get a line Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-15 10:57 -0800
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-15 12:05 -0800
Re: scanf used for to get a line jameskuyper@verizon.net - 2016-11-15 14:01 -0800
Re: scanf used for to get a line Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-16 10:54 -0800
Re: scanf used for to get a line Richard Damon <Richard@Damon-Family.org> - 2016-11-21 18:01 -0500
Re: scanf used for to get a line supercat@casperkitty.com - 2016-11-21 15:44 -0800
Re: scanf used for to get a line asetofsymbols@gmail.com - 2016-11-03 13:35 -0700
Re: scanf used for to get a line Keith Thompson <kst-u@mib.org> - 2016-11-03 13:50 -0700
Re: scanf used for to get a line ImperiusDamian <damianblack.wolf@gmail.com> - 2016-11-05 16:10 -0400
Re: scanf used for to get a line Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-01 11:39 +0000
Re: scanf used for to get a line asetofsymbols@gmail.com - 2016-11-01 05:47 -0700
Re: scanf used for to get a line Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-01 15:05 +0000
Re: scanf used for to get a line asetofsymbols@gmail.com - 2016-11-02 01:42 -0700
Page 1 of 2 [1] 2 Next page →
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2016-11-01 01:50 -0700 |
| Subject | scanf used for to get a line |
| Message-ID | <15ea8d6d-0173-491c-b6b5-b1c57dd61769@googlegroups.com> |
What about:
char a[1024], c;
int w, r;
r=scanf("%1024[^\n]%c",a,&c);
if(r<1)error();
in the case \n is 2 characters?
[toc] | [next] | [standalone]
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2016-11-01 01:55 -0700 |
| Message-ID | <89abb962-6011-4cc8-a684-770b5f092cb6@googlegroups.com> |
| In reply to | #95489 |
What about:
char a[1024], c;
int w, r;
r=scanf("%1024[^\n]%c",a,&c);
if(r<1)error();
in the case \n is 2 characters?
Where \n = 13,10 ...
[toc] | [prev] | [next] | [standalone]
| From | mark.bluemel@gmail.com |
|---|---|
| Date | 2016-11-01 03:55 -0700 |
| Message-ID | <236c25a6-8c18-4082-ab3a-86eb55fb2408@googlegroups.com> |
| In reply to | #95489 |
On Tuesday, 1 November 2016 08:50:54 UTC, asetof...@gmail.com wrote:
> What about:
> char a[1024], c;
> int w, r;
> r=scanf("%1024[^\n]%c",a,&c);
> if(r<1)error();
> in the case \n is 2 characters?
Scanf to read a line is a poor choice, but you need to understand that a
text stream, like stdin, will have platform specific line endings mapped
to a single character represented as '\n'
What are you actually trying to achieve?
[toc] | [prev] | [next] | [standalone]
| From | "Charles Richmond" <numerist@aquaporin4.com> |
|---|---|
| Date | 2016-11-03 11:23 -0500 |
| Message-ID | <nvfoa6$lsu$1@dont-email.me> |
| In reply to | #95494 |
<mark.bluemel@gmail.com> wrote in message
news:236c25a6-8c18-4082-ab3a-86eb55fb2408@googlegroups.com...
> On Tuesday, 1 November 2016 08:50:54 UTC, asetof...@gmail.com wrote:
>> What about:
>> char a[1024], c;
>> int w, r;
>> r=scanf("%1024[^\n]%c",a,&c);
>> if(r<1)error();
>> in the case \n is 2 characters?
>
> Scanf to read a line is a poor choice, but you need to understand that a
> text stream, like stdin, will have platform specific line endings mapped
> to a single character represented as '\n'
>
You might have fewer problems if you read the line with "fgets()" and then
use "sscanf()" to parse out the results.
--
numerist at aquaporin4 dot com
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-03 09:38 -0700 |
| Message-ID | <lnfun8zffj.fsf@kst-u.example.com> |
| In reply to | #95660 |
"Charles Richmond" <numerist@aquaporin4.com> writes:
> <mark.bluemel@gmail.com> wrote in message
> news:236c25a6-8c18-4082-ab3a-86eb55fb2408@googlegroups.com...
>> On Tuesday, 1 November 2016 08:50:54 UTC, asetof...@gmail.com wrote:
>>> What about:
>>> char a[1024], c;
>>> int w, r;
>>> r=scanf("%1024[^\n]%c",a,&c);
>>> if(r<1)error();
>>> in the case \n is 2 characters?
>>
>> Scanf to read a line is a poor choice, but you need to understand that a
>> text stream, like stdin, will have platform specific line endings mapped
>> to a single character represented as '\n'
>>
>
> You might have fewer problems if you read the line with "fgets()" and then
> use "sscanf()" to parse out the results.
But be careful. sscanf() has undefined behavior on numeric overflow.
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-03 10:08 -0700 |
| Message-ID | <5e06af91-eec8-42cd-87c4-99d2b448de84@googlegroups.com> |
| In reply to | #95663 |
On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote:
> But be careful. sscanf() has undefined behavior on numeric overflow.
If one wanted to write the simplest strictly-conforming program that would
e.g. read a line of input from stdin and:
1. If the input contains two signed numbers separated by a space, both
within the range of "long long", and their product is also within the
range of that type, output their product.
2. In all other cases, output any sequence of 0 to 1,000 characters and
exit.
How should one make that program most simply? All the approaches I can
think of seem absurdly complicated for what should be a very easy
requirement [especially given the latitude regarding error behavior]. Is
there any way to write the code simply and cleanly in strictly-conforming
fashion, without spending more code on the second requirement than the
first?
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-03 11:29 -0700 |
| Message-ID | <lnbmxwzab8.fsf@kst-u.example.com> |
| In reply to | #95666 |
supercat@casperkitty.com writes:
> On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote:
>> But be careful. sscanf() has undefined behavior on numeric overflow.
>
> If one wanted to write the simplest strictly-conforming program that would
> e.g. read a line of input from stdin and:
>
> 1. If the input contains two signed numbers separated by a space, both
> within the range of "long long", and their product is also within the
> range of that type, output their product.
>
> 2. In all other cases, output any sequence of 0 to 1,000 characters and
> exit.
>
> How should one make that program most simply?
I'd use strtoll() to parse the numbers. I find its interface a bit
clunky, but it does let you unambiguously determine whether the numbers
are in range (you need to set and test errno).
Determining whether their product is representable is a bit tricker, but
I have no doubt that it's been solved. A Google search for existing
solutions would probably be faster than writing a solution from scratch.
I'm not sure why you introduced this irrelevant requirement.
I don't know why your requirement #2 is so loose. It's easy enough to
print, say, "ERROR" on stderr.
(Incidentally, I intensely dislike the fact that numeric overflow in
scanf() has undefined behavior. It's clearly not accidental, but I'd
love to see it changed in the next edition of the standard. Libraries
already have to be able to parse numbers while reliably detecting
numeric overflow; see the strto*() functions.)
[...]
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-03 14:37 -0700 |
| Message-ID | <ba811315-30c5-49f8-b4c6-1a733e7a0ab2@googlegroups.com> |
| In reply to | #95673 |
On Thursday, November 3, 2016 at 1:28:36 PM UTC-5, Keith Thompson wrote: > supercat writes: > > On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote: > >> But be careful. sscanf() has undefined behavior on numeric overflow. > > > > If one wanted to write the simplest strictly-conforming program that would > > e.g. read a line of input from stdin and: > > > > 1. If the input contains two signed numbers separated by a space, both > > within the range of "long long", and their product is also within the > > range of that type, output their product. > > > > 2. In all other cases, output any sequence of 0 to 1,000 characters and > > exit. > > > > How should one make that program most simply? > > I'd use strtoll() to parse the numbers. I find its interface a bit > clunky, but it does let you unambiguously determine whether the numbers > are in range (you need to set and test errno). Before using strtoll, one would need to get the input into a string and then find where each part starts. > Determining whether their product is representable is a bit tricker, but > I have no doubt that it's been solved. A Google search for existing > solutions would probably be faster than writing a solution from scratch. > I'm not sure why you introduced this irrelevant requirement. The main point of the exercise was to process the input safely and without UB for all cases. The multiply was included to necessitate actually converting the input to a number (if the code simply had to output the values that were typed, it could simply echo the input). The language about the product being representable was to exempt the code from having to worry about the overflow case beyond preventing UB. > I don't know why your requirement #2 is so loose. It's easy enough to > print, say, "ERROR" on stderr. Efficiently detecting the overflow condition requires a bit of code, so I didn't want to require it. > (Incidentally, I intensely dislike the fact that numeric overflow in > scanf() has undefined behavior. It's clearly not accidental, but I'd > love to see it changed in the next edition of the standard. Libraries > already have to be able to parse numbers while reliably detecting > numeric overflow; see the strto*() functions.) I suspect that dates back to the time when many implementations tried to implement useful behaviors in many places where the Standard imposed no requirements. It's easy to imagine a version of "scanf" where the variables may be set to Unspecified (and unpredictable) values if the input is invalid. It's also not hard to imagine a version of "scanf" which, if input was coming from a console, might inform the user if an attempt was made to enter invalid data. Such notification might be done in ways outside the jurisdiction of the C Standard (triggering a buzzer, for example). There only simply way the Standard could allow both of the above was to make the behavior UB. The first would not qualify as Implementation- Defined, and the second would not qualify as yielding an Unspecified or Indeterminate value (because of the side-effect of triggering the buzzer).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-03 16:34 -0700 |
| Message-ID | <lnpomcxhlt.fsf@kst-u.example.com> |
| In reply to | #95698 |
supercat@casperkitty.com writes:
>> supercat writes:
>> > On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote:
>> >> But be careful. sscanf() has undefined behavior on numeric overflow.
>> >
>> > If one wanted to write the simplest strictly-conforming program that would
>> > e.g. read a line of input from stdin and:
>> >
>> > 1. If the input contains two signed numbers separated by a space, both
>> > within the range of "long long", and their product is also within the
>> > range of that type, output their product.
>> >
>> > 2. In all other cases, output any sequence of 0 to 1,000 characters and
>> > exit.
>> >
>> > How should one make that program most simply?
>>
>> I'd use strtoll() to parse the numbers. I find its interface a bit
>> clunky, but it does let you unambiguously determine whether the numbers
>> are in range (you need to set and test errno).
>
> Before using strtoll, one would need to get the input into a string and
> then find where each part starts.
No, you just need to get the input into a string (fgets() will do that,
or something more sophisticated if you can't place an upper bound on the
input line length). strtoll will tell you where in the string the
number ends if you ask it to.
>> Determining whether their product is representable is a bit tricker, but
>> I have no doubt that it's been solved. A Google search for existing
>> solutions would probably be faster than writing a solution from scratch.
>> I'm not sure why you introduced this irrelevant requirement.
>
> The main point of the exercise was to process the input safely and without
> UB for all cases. The multiply was included to necessitate actually
> converting the input to a number (if the code simply had to output the
> values that were typed, it could simply echo the input). The language
> about the product being representable was to exempt the code from having
> to worry about the overflow case beyond preventing UB.
You could have just specified storing the input into objects of type
long long. Multiplying while avoiding overflow just adds a layer of
complexity that wasn't in the original problem.
>> I don't know why your requirement #2 is so loose. It's easy enough to
>> print, say, "ERROR" on stderr.
>
> Efficiently detecting the overflow condition requires a bit of code, so I
> didn't want to require it.
Methods that don't detect the overflow tend to have undefined behavior.
strtoll() can reliably detect overflow.
>> (Incidentally, I intensely dislike the fact that numeric overflow in
>> scanf() has undefined behavior. It's clearly not accidental, but I'd
>> love to see it changed in the next edition of the standard. Libraries
>> already have to be able to parse numbers while reliably detecting
>> numeric overflow; see the strto*() functions.)
>
> I suspect that dates back to the time when many implementations tried to
> implement useful behaviors in many places where the Standard imposed no
> requirements.
>
> It's easy to imagine a version of "scanf" where the variables may be set
> to Unspecified (and unpredictable) values if the input is invalid.
It's also easy to imagine an implementation that would have an signed
integer overflow given an out of range input. Given the age of scanf, I
suspect early implementations did that, because they simply ignored the
issue of overflow.
> It's also not hard to imagine a version of "scanf" which, if input was
> coming from a console, might inform the user if an attempt was made to
> enter invalid data. Such notification might be done in ways outside the
> jurisdiction of the C Standard (triggering a buzzer, for example).
That doesn't seem plausible. The idea of treating standard input
consistently regardless of where it's coming from is quite old. I don't
think even a very old implementation of scanf would have triggered a
buzzer on an error.
> There only simply way the Standard could allow both of the above was to
> make the behavior UB. The first would not qualify as Implementation-
> Defined, and the second would not qualify as yielding an Unspecified or
> Indeterminate value (because of the side-effect of triggering the buzzer).
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-04 10:21 -0700 |
| Message-ID | <108db18d-12c1-4eaa-afc9-59e7c0ca7798@googlegroups.com> |
| In reply to | #95706 |
On Thursday, November 3, 2016 at 6:35:00 PM UTC-5, Keith Thompson wrote: > supercat writes: > > Before using strtoll, one would need to get the input into a string and > > then find where each part starts. > > No, you just need to get the input into a string (fgets() will do that, > or something more sophisticated if you can't place an upper bound on the > input line length). strtoll will tell you where in the string the > number ends if you ask it to. The Standard the scenarios in which a newline is encountered, no newline is encountered before enough characters are read, the end of the file is encountered *and no characters have been read into the array*, or a read-error occurs. I see nothing that would characterize EOF as a read error, nor do I see anything that would describe the behavior in case an EOF is encountered after characters have been read. Those factors put together would seem to suggest that nasal demons in such a scenario would not make an implementation non-conforming. > > It's easy to imagine a version of "scanf" where the variables may be set > > to Unspecified (and unpredictable) values if the input is invalid. > > It's also easy to imagine an implementation that would have an signed > integer overflow given an out of range input. Given the age of scanf, I > suspect early implementations did that, because they simply ignored the > issue of overflow. I would expect a typical scanf implementation would look for a minus sign, parse a number as unsigned, and then convert the result to a signed type if needed. Unless one wants to invert each digit as it's added, it will be necessary to build the number in positive form, so code may as well use unsigned. Explicit overflow checks might be needed in a few cases to prevent UB, but the cost of such checks would be such a tiny part of the cost of scanf I see no disadvantage to requiring them. > > It's also not hard to imagine a version of "scanf" which, if input was > > coming from a console, might inform the user if an attempt was made to > > enter invalid data. Such notification might be done in ways outside the > > jurisdiction of the C Standard (triggering a buzzer, for example). > > That doesn't seem plausible. The idea of treating standard input > consistently regardless of where it's coming from is quite old. I don't > think even a very old implementation of scanf would have triggered a > buzzer on an error. It would be implausible that a Unix implementation would do such a thing. Not all systems support console redirection, however. On many systems which don't support console redirection, console input *must* be treated differently from file input, at least at the OS level.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-04 11:46 -0700 |
| Message-ID | <lnr36rw0aq.fsf@kst-u.example.com> |
| In reply to | #95774 |
supercat@casperkitty.com writes:
> On Thursday, November 3, 2016 at 6:35:00 PM UTC-5, Keith Thompson wrote:
>> supercat writes:
>> > Before using strtoll, one would need to get the input into a string and
>> > then find where each part starts.
>>
>> No, you just need to get the input into a string (fgets() will do that,
>> or something more sophisticated if you can't place an upper bound on the
>> input line length). strtoll will tell you where in the string the
>> number ends if you ask it to.
>
> The Standard the scenarios in which a newline is encountered, no newline
> is encountered before enough characters are read, the end of the file is
> encountered *and no characters have been read into the array*, or a
> read-error occurs. I see nothing that would characterize EOF as a read
> error, nor do I see anything that would describe the behavior in case
> an EOF is encountered after characters have been read. Those factors put
> together would seem to suggest that nasal demons in such a scenario would
> not make an implementation non-conforming.
Can you be more specific about the scenario you're talking about?
What I'm suggesting is:
1. Read a line into a string using fgets(), or something more
sophisticated if you want to handle arbitrarily long lines. The
resulting string may or may not have a trailing '\n', and it may or may
not be empty.
2. Use strtoll() to scan long long values from the string, storing them
in objects of type long long.
I see no possibility for nasal demons if the above is done correctly.
[...]
>> > It's also not hard to imagine a version of "scanf" which, if input was
>> > coming from a console, might inform the user if an attempt was made to
>> > enter invalid data. Such notification might be done in ways outside the
>> > jurisdiction of the C Standard (triggering a buzzer, for example).
>>
>> That doesn't seem plausible. The idea of treating standard input
>> consistently regardless of where it's coming from is quite old. I don't
>> think even a very old implementation of scanf would have triggered a
>> buzzer on an error.
>
> It would be implausible that a Unix implementation would do such a thing.
> Not all systems support console redirection, however. On many systems
> which don't support console redirection, console input *must* be treated
> differently from file input, at least at the OS level.
The early history of scanf, like that of C, is largely Unix-specific.
It was originally defined and implemented on Unix. I presume that
its behavior on other systems, for early ports, would have been
designed to emulate the Unix behavior. I'd be surprised if scanf()
were ever designed to trigger a buzzer on any system to which it
was ported. (Feel free to present a real-world counterexample.)
It already has error-reporting facilities, and any interactive
response to an error should be up to the program, not to the
library routine.
Not that any of this really matters. Regardless of the history,
the fact that the *scanf() functions have undefined behavior on
numeric overflow is, in my opinion and I think in yours, a flaw
in the standard that should be corrected. Treating overflow as a
matching failure is probably the simples approach. The fact that
the strto*() functions (which I think are newer than *scanf()) are
reqiured to handle numeric overflow gracefully strongly suggests
that such a change would not be a burden on implementers.
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-04 15:04 -0700 |
| Message-ID | <3c58680e-35cb-4c1f-b53f-91d8d3fbf2f9@googlegroups.com> |
| In reply to | #95785 |
On Friday, November 4, 2016 at 1:45:20 PM UTC-5, Keith Thompson wrote:
> supercat writes:
> > The Standard the scenarios in which a newline is encountered, no newline
> > is encountered before enough characters are read, the end of the file is
> > encountered *and no characters have been read into the array*, or a
> > read-error occurs. I see nothing that would characterize EOF as a read
> > error, nor do I see anything that would describe the behavior in case
> > an EOF is encountered after characters have been read. Those factors put
> > together would seem to suggest that nasal demons in such a scenario would
> > not make an implementation non-conforming.
>
> Can you be more specific about the scenario you're talking about?
Standard input contains some characters followed by EOF, with no intervening
newline.
The Standard describes behavior in many scenarios, but the only way in which
it could be construed as defining behavior when a file ends with a partial
line would be if such a partial line was considered an error. I don't see
anything in the Standard, however, which would indicate that hitting
end-of-file when the preceding character isn't a newline should be considered
an error condition.
> The early history of scanf, like that of C, is largely Unix-specific.
> It was originally defined and implemented on Unix. I presume that
> its behavior on other systems, for early ports, would have been
> designed to emulate the Unix behavior.
Many other systems have a natural input model which behaves like "raw" mode
in Unix, and either require that line input be handled by the application
or else have separate functions to read a line from the console or read a
single character without line buffering. While the C dialects I have used
often implement a getch() function for raw input and have getchar()
behave like Unix cooked mode, I haven't used console I/O on any dialects
for systems that didn't support console redirection. I would not think it
would have been implausible, especially in the days before the Standard,
that an implementation would have getchar() call the get-raw-character
routine and have gets() call a get-line routine.
> I'd be surprised if scanf()
> were ever designed to trigger a buzzer on any system to which it
> was ported. (Feel free to present a real-world counterexample.)
> It already has error-reporting facilities, and any interactive
> response to an error should be up to the program, not to the
> library routine.
I don't know if any counter-examples. On the other hand, since the
semantics of scanf make reasonable error-trapping behavior at the
application level awkward, and I don't think it's hard to imagine--
especially in the days before the Standard--that an implementor might
decide to implement design their "scanf" function in such a way that
scanf("%d %d", &var1, &var2); would be a reasonable way to read two
numbers from the console.
> Not that any of this really matters. Regardless of the history,
> the fact that the *scanf() functions have undefined behavior on
> numeric overflow is, in my opinion and I think in yours, a flaw
> in the standard that should be corrected. Treating overflow as a
> matching failure is probably the simples approach. The fact that
> the strto*() functions (which I think are newer than *scanf()) are
> reqiured to handle numeric overflow gracefully strongly suggests
> that such a change would not be a burden on implementers.
I think we're in agreement there.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-04 16:44 -0700 |
| Message-ID | <ln7f8ix12l.fsf@kst-u.example.com> |
| In reply to | #95805 |
supercat@casperkitty.com writes:
> On Friday, November 4, 2016 at 1:45:20 PM UTC-5, Keith Thompson wrote:
>> supercat writes:
>> > The Standard the scenarios in which a newline is encountered, no newline
>> > is encountered before enough characters are read, the end of the file is
>> > encountered *and no characters have been read into the array*, or a
>> > read-error occurs. I see nothing that would characterize EOF as a read
>> > error, nor do I see anything that would describe the behavior in case
>> > an EOF is encountered after characters have been read. Those factors put
>> > together would seem to suggest that nasal demons in such a scenario would
>> > not make an implementation non-conforming.
>>
>> Can you be more specific about the scenario you're talking about?
>
> Standard input contains some characters followed by EOF, with no intervening
> newline.
>
> The Standard describes behavior in many scenarios, but the only way in which
> it could be construed as defining behavior when a file ends with a partial
> line would be if such a partial line was considered an error. I don't see
> anything in the Standard, however, which would indicate that hitting
> end-of-file when the preceding character isn't a newline should be considered
> an error condition.
N1570 7.21.2p2 says:
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.
If the implementation does require a terminating new-line and a given
stream doesn't have one, then my interpretation is that the behavior of
reading that stream is undefined.
That's unlikely to be a problem in practice. I speculate that it's
intended mainly to cater to systems with complex text file formats,
where an ill-formed text file might be unreadable. In particular, I
believe the new-line is *not* required on Unix-like systems, and
probably not on Windows either. Calling fgets() at the end of such a
file would just give the last line as a string with no trailing
new-line.
[...]
>> I'd be surprised if scanf()
>> were ever designed to trigger a buzzer on any system to which it
>> was ported. (Feel free to present a real-world counterexample.)
>> It already has error-reporting facilities, and any interactive
>> response to an error should be up to the program, not to the
>> library routine.
>
> I don't know if any counter-examples. On the other hand, since the
> semantics of scanf make reasonable error-trapping behavior at the
> application level awkward, and I don't think it's hard to imagine--
> especially in the days before the Standard--that an implementor might
> decide to implement design their "scanf" function in such a way that
> scanf("%d %d", &var1, &var2); would be a reasonable way to read two
> numbers from the console.
Apart from the numeric overflow problem, that *is* a reasonable way to
read two numbers from the console (assuming you don't require them to be
on the same line). Was that intended to have something to do with the
buzzer scanario?
[...]
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-04 17:13 -0700 |
| Message-ID | <0d349302-0a98-4fa3-a368-8ac76ca8c546@googlegroups.com> |
| In reply to | #95811 |
On Friday, November 4, 2016 at 6:44:22 PM UTC-5, Keith Thompson wrote:
> supercat writes:
> > The Standard describes behavior in many scenarios, but the only way in which
> > it could be construed as defining behavior when a file ends with a partial
> > line would be if such a partial line was considered an error. I don't see
> > anything in the Standard, however, which would indicate that hitting
> > end-of-file when the preceding character isn't a newline should be considered
> > an error condition.
>
> N1570 7.21.2p2 says:
>
> 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.
>
> If the implementation does require a terminating new-line and a given
> stream doesn't have one, then my interpretation is that the behavior of
> reading that stream is undefined.
Does anything in the Standard specify the behavior in the event that the
implementation does not require a newline before EOF, and indeed none
exists?
> That's unlikely to be a problem in practice. I speculate that it's
> intended mainly to cater to systems with complex text file formats,
> where an ill-formed text file might be unreadable. In particular, I
> believe the new-line is *not* required on Unix-like systems, and
> probably not on Windows either. Calling fgets() at the end of such a
> file would just give the last line as a string with no trailing
> new-line.
Would anything in the Standard guarantee sane behavior, or are you merely
assuming that because it would be silly for implementations to do anything
nasty, implementations won't do anything nasty?
I've certainly seen programs where failure to include a newline after the
last line of a file would cause the program to process the line preceding
the last line twice; I have no idea if they were written in C or some
other language, but certainly line-input routines which behave badly on
files that end with partial lines are not unknown in this world.
> > I don't know if any counter-examples. On the other hand, since the
> > semantics of scanf make reasonable error-trapping behavior at the
> > application level awkward, and I don't think it's hard to imagine--
> > especially in the days before the Standard--that an implementor might
> > decide to implement design their "scanf" function in such a way that
> > scanf("%d %d", &var1, &var2); would be a reasonable way to read two
> > numbers from the console.
>
> Apart from the numeric overflow problem, that *is* a reasonable way to
> read two numbers from the console (assuming you don't require them to be
> on the same line). Was that intended to have something to do with the
> buzzer scanario?
What happens if someone types x, or 12x, or 12 34x, etc.? A smart routine
for an interactive system could validate input as it was typed and reject
invalid characters immediately. I don't know that any implementations
defined their scanf routines to do so, but a routine that did so could
certainly be helpful.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-04 19:12 -0700 |
| Message-ID | <ln37j6wu7n.fsf@kst-u.example.com> |
| In reply to | #95813 |
supercat@casperkitty.com writes:
> On Friday, November 4, 2016 at 6:44:22 PM UTC-5, Keith Thompson wrote:
>> supercat writes:
>> > The Standard describes behavior in many scenarios, but the only way in which
>> > it could be construed as defining behavior when a file ends with a partial
>> > line would be if such a partial line was considered an error. I don't see
>> > anything in the Standard, however, which would indicate that hitting
>> > end-of-file when the preceding character isn't a newline should be considered
>> > an error condition.
>>
>> N1570 7.21.2p2 says:
>>
>> 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.
>>
>> If the implementation does require a terminating new-line and a given
>> stream doesn't have one, then my interpretation is that the behavior of
>> reading that stream is undefined.
>
> Does anything in the Standard specify the behavior in the event that the
> implementation does not require a newline before EOF, and indeed none
> exists?
The behavior of what? A stream has no behavior by itself. The behavior
of any function that operates on a FILE* is defined by the description
of that function. If there's some construct whose behavior you think is
not defined in that case, please specify what it is.
>> That's unlikely to be a problem in practice. I speculate that it's
>> intended mainly to cater to systems with complex text file formats,
>> where an ill-formed text file might be unreadable. In particular, I
>> believe the new-line is *not* required on Unix-like systems, and
>> probably not on Windows either. Calling fgets() at the end of such a
>> file would just give the last line as a string with no trailing
>> new-line.
>
> Would anything in the Standard guarantee sane behavior, or are you merely
> assuming that because it would be silly for implementations to do anything
> nasty, implementations won't do anything nasty?
See above.
> I've certainly seen programs where failure to include a newline after the
> last line of a file would cause the program to process the line preceding
> the last line twice; I have no idea if they were written in C or some
> other language, but certainly line-input routines which behave badly on
> files that end with partial lines are not unknown in this world.
Yes, some programs have bugs.
>> > I don't know if any counter-examples. On the other hand, since the
>> > semantics of scanf make reasonable error-trapping behavior at the
>> > application level awkward, and I don't think it's hard to imagine--
>> > especially in the days before the Standard--that an implementor might
>> > decide to implement design their "scanf" function in such a way that
>> > scanf("%d %d", &var1, &var2); would be a reasonable way to read two
>> > numbers from the console.
>>
>> Apart from the numeric overflow problem, that *is* a reasonable way to
>> read two numbers from the console (assuming you don't require them to be
>> on the same line). Was that intended to have something to do with the
>> buzzer scanario?
>
> What happens if someone types x, or 12x, or 12 34x, etc.? A smart routine
> for an interactive system could validate input as it was typed and reject
> invalid characters immediately. I don't know that any implementations
> defined their scanf routines to do so, but a routine that did so could
> certainly be helpful.
Sure. scanf doesn't do that.
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-05 14:10 -0700 |
| Message-ID | <6e55e023-285a-4041-9b7f-90fa65652279@googlegroups.com> |
| In reply to | #95816 |
On Friday, November 4, 2016 at 9:11:38 PM UTC-5, Keith Thompson wrote: > The behavior of what? A stream has no behavior by itself. The behavior > of any function that operates on a FILE* is defined by the description > of that function. If there's some construct whose behavior you think is > not defined in that case, please specify what it is. What part of the Standard specifies the behavior of fgets in case stdin returns one character that isn't a newline and then reports EOF but does not report an error? The Standard describes the behavior in cases where a stream reports an EOF before returning any characters, and in cases where the stream reports an error, but I do not see any description of what fgets is required to do in case the stream returns one or more characters followed by EOF, but does not report an error.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-11-05 14:22 -0700 |
| Message-ID | <ln60o1vcyd.fsf@kst-u.example.com> |
| In reply to | #95857 |
supercat@casperkitty.com writes:
> On Friday, November 4, 2016 at 9:11:38 PM UTC-5, Keith Thompson wrote:
>> The behavior of what? A stream has no behavior by itself. The behavior
>> of any function that operates on a FILE* is defined by the description
>> of that function. If there's some construct whose behavior you think is
>> not defined in that case, please specify what it is.
>
> What part of the Standard specifies the behavior of fgets in case stdin
> returns one character that isn't a newline and then reports EOF but does
> not report an error? The Standard describes the behavior in cases where
> a stream reports an EOF before returning any characters, and in cases
> where the stream reports an error, but I do not see any description of
> what fgets is required to do in case the stream returns one or more
> characters followed by EOF, but does not report an error.
N1570 7.21.7.2p1:
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.
How is that unclear in the case you describe?
--
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 | 2016-11-15 10:57 -0800 |
| Message-ID | <kfneg2csh95.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #95666 |
supercat@casperkitty.com writes: > On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote: >> But be careful. sscanf() has undefined behavior on numeric overflow. > > If one wanted to write the simplest strictly-conforming program that would > e.g. read a line of input from stdin and: > > 1. If the input contains two signed numbers separated by a space, both > within the range of "long long", and their product is also within the > range of that type, output their product. > > 2. In all other cases, output any sequence of 0 to 1,000 characters and > exit. > > How should one make that program most simply? [...] The problem statement is self-contradictory. The output depends on implementation-defined behavior, so the program cannot possibly be strictly conforming.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-11-15 12:05 -0800 |
| Message-ID | <0e6d8bbf-e13a-4a39-bfac-3f9113734f13@googlegroups.com> |
| In reply to | #96629 |
On Tuesday, November 15, 2016 at 12:57:50 PM UTC-6, Tim Rentsch wrote: > supercat writes: > > > On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote: > >> But be careful. sscanf() has undefined behavior on numeric overflow. > > > > If one wanted to write the simplest strictly-conforming program that would > > e.g. read a line of input from stdin and: > > > > 1. If the input contains two signed numbers separated by a space, both > > within the range of "long long", and their product is also within the > > range of that type, output their product. > > > > 2. In all other cases, output any sequence of 0 to 1,000 characters and > > exit. > > > > How should one make that program most simply? [...] > > The problem statement is self-contradictory. The output depends > on implementation-defined behavior, so the program cannot > possibly be strictly conforming. In what way would it depend upon implementation-defined behaviors to a greater extent than just about *any* other possibly-useful program? It would be possible to interpret the requirements for "strictly-conforming" programs so strictly that almost nothing could be done by strictly- conforming program, but under such an interpretation the Standard would be pretty much useless.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2016-11-15 14:01 -0800 |
| Message-ID | <924963d3-cc3b-4001-9de5-054713e8b98a@googlegroups.com> |
| In reply to | #96633 |
On Tuesday, November 15, 2016 at 3:05:40 PM UTC-5, supe...@casperkitty.com wrote: > On Tuesday, November 15, 2016 at 12:57:50 PM UTC-6, Tim Rentsch wrote: > > supercat writes: > > > > > On Thursday, November 3, 2016 at 11:38:40 AM UTC-5, Keith Thompson wrote: > > >> But be careful. sscanf() has undefined behavior on numeric overflow. > > > > > > If one wanted to write the simplest strictly-conforming program that would > > > e.g. read a line of input from stdin and: > > > > > > 1. If the input contains two signed numbers separated by a space, both > > > within the range of "long long", and their product is also within the > > > range of that type, output their product. > > > > > > 2. In all other cases, output any sequence of 0 to 1,000 characters and > > > exit. > > > > > > How should one make that program most simply? [...] > > > > The problem statement is self-contradictory. The output depends > > on implementation-defined behavior, so the program cannot > > possibly be strictly conforming. > > In what way would it depend upon implementation-defined behaviors to a > greater extent than just about *any* other possibly-useful program? Most useful programs are not strictly conforming. In this particular case, it's because the range of "long long" is implementation-defined. > ... It > would be possible to interpret the requirements for "strictly-conforming" > programs so strictly that almost nothing could be done by strictly- > conforming program, That would be a correct interpretation of those requirements. Such a program "shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior" (4p5). I'm curious how you could interpret that requirement as allowing a program to have output which depends upon the range of long long. It's possible for a strictly conforming program to be useful, but it's pretty rare - there's an awfully large variety of ways that code can have "unspecified, undefined, and implementation-defined behavior", even if we ignore that virtually every aspect of the I/O functions falls into that category. > ... but under such an interpretation the Standard would be > pretty much useless. Why? The only thing that the standard says about "strictly conforming" programs is that an implementation is required to accept them - and the standard doesn't even define what "accept" means in this context, make that a fairly meaningless requirement. Everything else that the standard says applies just as well to programs that aren't strictly conforming, so long as they don't have undefined behavior. An implementation is free to not accept such programs, but if it chooses to translate and execute them, the resulting behavior is constrained to meet all of the applicable requirements specified by the standard. The overwhelming majority of all useful code falls into this category, not the "strictly conforming" category.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web