Re: Bug in scanf?
Jacob Pipkin <[email protected]> Wed, 10 Dec 2025 08:04:26 -0600
| Newsgroups | gmane.os.netbsd.devel.userlevel |
|---|---|
| Message-ID | <[email protected]> |
On 12/10/25 03:07, Anders Magnusson wrote: > Den 2025-12-09 kl. 20:22, skrev Roland Illig: >> Am 09.12.2025 um 09:27 schrieb Anders Magnusson: >>> Morning, >>> >>> Den 2025-12-09 kl. 03:49, skrev Robert Elz: >>>> Date: Mon, 8 Dec 2025 20:45:00 +0100 >>>> From: Anders Magnusson<[email protected]> >>>> Message-ID:<[email protected]> >>>> >>>> | I just stumbled over something which may be a bug in scanf()...? >>>> | This example is in C99 7.19.6.2 clause 20. >>>> >>>> Yes, but nowhere there does it say what the result should be in the >>>> case that you give, and I think you're arriving at an incorrect >>>> conclusion. >>> Sorry, but I think that is very clear? The input scanning should stop >>> whenever something unwanted is read. >>> And as you noticed in the followup mail; this was an example from the >>> standard which was what I was referring to :-) >>> >>> Also, as you note it should accept whatever strtod() do, _but_: C99 note >>> 242 (C23 note 348) says: >>> >>> "fscanf pushes back at most one input character onto the input stream. >>> Therefore, some sequences >>> that are acceptable to strtod, strtol, etc., are unacceptable to >>> fscanf.". >>> >>> which is what should happen here (and the reason "100ergs" should fail >>> for %f in *scanf()). >>> When reading the 'r' the scanning for %f fails and it returns. As the >>> standard says...? >> That's exactly the reasoning I had in mind. I wonder though why fscanf >> is _required_ to reject this sequence, instead of allowing an >> implementation with a larger pushback buffer to accept this string, thus >> making this decision a quality-of-implementation issue. The C99 >> rationale doesn't mention this particular possibility. > The problem here is that it should be deterministic how the input will > be parsed and not vary depending on which stdio implementation there is. > > The BSD stdio package gives this result: > count=3 quant=100.000000 units=ergs item=energy > > Glibc gives this: (which also the original stdio package on 2BSD does) > count=3 quant=100.000000 units=rgs item=energy > > But the C standard says that it should return count=0 which neither of > them does. > > It would be interesting to know how some other (legacy) OSes parses, > like Solaris? Any takers available? :-) > Code snippet below: > > #include <stdio.h> > > main() > { > int count; float quant; char units[21], item[21]; > count = sscanf("100ergs of energy\n", > "%f%20s of %20s", &quant, units, item); > printf("count=%d quant=%f units=%s item=%s\n", > count, quant, units, item); > } > > > > $ uname -a SunOS aurora 5.11 illumos-c2cbc6b847 i86pc i386 i86pc $ cat test.c #include <stdio.h> main() { int count; float quant; char units[21], item[21]; count = sscanf("100ergs of energy\n", "%f%20s of %20s", &quant, units, item); printf("count=%d quant=%f units=%s item=%s\n", count, quant, units, item); } $ cc -o test test.c test.c:3:1: warning: return type defaults to 'int' [-Wimplicit-int] 3 | main() | ^~~~ $ ./test count=0 quant=-0.000000 units=LG item=P $