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
$