Re: Bug in scanf?

Anders Magnusson <[email protected]> Wed, 10 Dec 2025 10:07:15 +0100
Newsgroups gmane.os.netbsd.devel.userlevel
Message-ID <[email protected]>
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);
}